12

我将 Entity Framework 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 即可加载所有RecommendationAND对象。User

把钱拿出来。

编辑我对讨论这是一个好还是坏的架构并不是很感兴趣。为了这个问题,我已经简化了我的场景。你能用 EF API 做我要求的事情吗?

编辑 2

拉迪斯拉夫的编辑提供了一种新方法的希望,但似乎我并不完全在那里。

我可以通过这个实现我想要的:

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

这种方法不适用于LoadProperty...

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

...因为它因错误而失败...

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

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

4

4 回答 4

5

这是一个老问题,但在 EF6 中,您可以在这样的实体上完成加载依赖对象:

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

这将加载所有Recommendations及其相关Users的给定seller

于 2014-02-26T18:44:54.883 回答
3

我认为这是您的存储库的一项工作,在您的情况下,它应该公开诸如 GetFullSeller(由 Include 加载的所有属性)和 GetSeller(仅基本实体)之类的方法。

编辑:

有几种方法可以在 EF v4 中加载导航属性。

没有自动加载。

于 2010-09-08T19:49:15.040 回答
2

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

一个解决方案可以是创建您的卖家类的部分类(由 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");
  }

}
于 2010-11-03T17:03:28.830 回答
0

与其将实际的域对象(EntityObjects)传递给视图,您可能希望使用控制器将它们映射到模型对象中,该对象更好地表示您的视图应该实际显示的内容。这将减少视图中所需的逻辑量,并具有避免在上下文过期后传递 EntityObjects 的令人愉快的副作用。

根据您的编辑进行编辑

不,API 没有办法获取单个实体对象并使其类型的所有其他实体对象在加载的同时被延迟填充特定属性。Include您最好首先使用您在问题中显示的提及来拉出所有项目。

于 2010-09-08T19:59:14.017 回答