2010-09-08 143 views
12

我正在使用实体框架4与MVC,并需要确保任何引用的实体我想在我的视图中使用已加载控制器方法返回之前,否则视图吐出恐惧:实体框架 - 急切加载相关实体

ObjectContext实例已被处置,不能再用于需要连接的操作。

当从上下文直选择,我可以只使用Include(string)方法迫使其被包括在生成的SQL查询:

var sellers = context.Sellers.Include("Recommendations.User").ToList(); 

但是,如果我有(例如)一个辅助方法接受一个实体并需要加载所有项目,没有可用的方法Include

void Test(Seller seller) 
{ 
    // ensure all recommendations and their users are loaded 
} 

蛮力方法是遍历它们:

foreach (var recommendation in seller.Recommendations) 
    recommendation.User.ToString(); // just force a load 

如果我有100项建议,这将创造幕后的101个SQL查询。理想情况下,我需要一种方法/方法,只需一次访问SQL即可加载所有的RecommendationUser对象。

让我看看钱。

编辑我并不是真的有兴趣讨论这是一个好还是坏的架构。为了这个问题,我简化了我的场景。你可以用EF API来做什么吗?

EDIT 2

Ladislav's edit的新方法带来了希望,但似乎我不太有。

我可以实现我通过该想什么:

context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id); 

这种方法不使用LoadProperty工作...

context.LoadProperty(seller, "Recommendations.User"); 

...因为它失败,出现错误...

无法找到指定的导航属性Recommendations.User。

如果您没有对上下文的引用,则这两种方法都不起作用。

+0

虽然这不能回答你的问题(因此我把它作为评论发布) - 它确实讨论了加载相关实体,因为它目前在EF6中工作。这也是搜索“实体框架负载相关实体”时在Google中出现的第一个SOF链接:http://msdn.microsoft.com/en-us/data/jj574232。所以我想我会分享.. – 2014-05-30 14:12:38

回答

3

我认为这是你的仓库的工作,应该在你的情况下公开像GetFullSeller(包含所有属性加载)和GetSeller(只有基本实体)的方法。

编辑:

有几种方法如何加载在EF v4的导航性能。(使用include)

  • 延迟加载由ObjectContext.LoadProperty
  • 明确装载

    • 预先加载(不适用于POCO工作)

    没有自动加载。

  • +1

    这是否意味着你只能使用直接来自存储库的对象?如果你通过WCF收到一个实体,然后想要附加它并在其上填充更多的字段,以便在最终保存之前执行更多转换,该怎么办?无论如何,我不认为这是一个架构问题。我只想知道API是否支持这一点,如果不支持,为什么不。 – 2010-09-08 19:57:52

    0

    不是通过您的实际域对象(EntityObject S)的观点相反,你可能需要使用您的控制器将它们映射成一个模型对象更好地代表了你的观点实际上应该显示。这将减少视图中所需的逻辑数量,并具有避免在其上下文过期后传递EntityObjects的令人愉快的副作用。

    编辑根据您的修改:

    没有,API没有办法采取单一的实体对象,使这是在同一时间,它是装载它的类型的所有其他实体对象一举以一种特殊的财产为懒散。你最好把所有的东西放在首位,使用Include提及,就像你在你的问题中提到的一样。

    +0

    感谢您的回答。为了清晰起见,我简化了案例。我确实使用了“视图模型”,以至于我的观点几乎没有任何逻辑。我的模型与关系密切相关,我不想在视图模型中重新创建该层次结构,所以我有一个基础级视图模型,它有一些实体枚举。就我而言,我需要在枚举中对另一个实体进行解引用。这不是一个真正的体系结构问题,就像API一样。 – 2010-09-08 20:04:21

    +0

    根据你的编辑;)这不是我想要做的。我有一个卖家。我需要加载所有卖家的建议。在每一项建议中,我都需要加载相应的用户。我不需要加载任何其他卖家。 – 2010-09-08 20:05:43

    +0

    如果我可以发明这个API,我会说'seller.Load(“Recommendations.User”)',就像我在原始实体集合查询中所做的那样(如OP所示)。 – 2010-09-08 20:06:40

    2

    我处于同样的情况。我认为使用EF很容易陷入101查询问题。

    解决方案可以创建Seller类的部分类(由EF生成),并实现返回IQueryable的GetSubclassNameQ以及返回具有预加载的IQueryable的GetSubclassNameQFull。

    public partial class Seller{ 
    
        public IQueryable<Recommendation> GetRecommendationsQ(EntityContainer entitycontainer) { 
        return entitycontainer.Recommendations; 
        }  
    
        public IQueryable<Recommendation> GetRecommendationsQFull(EntityContainer entitycontainer) { 
        return this.GetRecommendationsQ(entitycontainer).Include("Recommendations.User"); 
        } 
    
        public IQueryable<Recommendation> GetRecommendationsQ() { 
        return GetRecommendationsQ(new EntityContainer()); 
        } 
    
        public IQueryable<Recommendation> GetRecommendationsQFull() { 
        return this.GetRecommendationsQ().Include("Recommendations.User"); 
        } 
    
    } 
    
    5

    这是一个老问题,但在EF6可以完成对一个实体加载依赖对象,如this

    context.Entry(seller).Collection(s => s.Recommendations).Query().Include(r => r.User)).Load(); 
    

    这将加载所有Recommendations和给定seller

    及其相关 Users
    相关问题