Dre*_*kes 12 .net entity-framework eager-loading entity-framework-4
我正在使用带有MVC的Entity Framework 4,并且需要确保在我的视图中使用的任何引用实体在控制器方法返回之前已经加载,否则视图会吐出可怕的:
ObjectContext实例已被释放,不能再用于需要连接的操作.
直接从上下文中选择时,我可以使用该Include(string)
方法强制它们包含在生成的SQL查询中:
var sellers = context.Sellers.Include("Recommendations.User").ToList();
Run Code Online (Sandbox Code Playgroud)
但是,如果我(例如)一个接受实体并需要加载所有项目的辅助方法,则没有Include
可用的方法.
void Test(Seller seller)
{
// ensure all recommendations and their users are loaded
}
Run Code Online (Sandbox Code Playgroud)
蛮力方法是循环它们:
foreach (var recommendation in seller.Recommendations)
recommendation.User.ToString(); // just force a load
Run Code Online (Sandbox Code Playgroud)
如果我有100条建议,这将在幕后创建101个SQL查询.理想情况下,我想要一个方法/方法,只需一次SQL访问即可加载所有Recommendation
AND User
对象.
给我看看钱款.
编辑我真的不想讨论这是一个好的或坏的架构.为了这个问题,我简化了我的方案.你能用EF API做我想问的吗?
编辑2
拉迪斯拉夫的编辑提供了一种新方法的希望,但似乎我并不存在.
我可以通过这个实现我想要的东西:
context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id);
Run Code Online (Sandbox Code Playgroud)
这种方法不适用于LoadProperty
......
context.LoadProperty(seller, "Recommendations.User");
Run Code Online (Sandbox Code Playgroud)
......因为错误而失败了......
找不到指定的导航属性Recommendations.User.
如果您没有对上下文的引用,这些方法都不起作用.
这是一个老问题,但在EF6中,您可以在实体上完成加载相关对象,如下所示:
context.Entry(seller).Collection(s => s.Recommendations).Query().Include(r => r.User)).Load();
Run Code Online (Sandbox Code Playgroud)
这将加载所有Recommendations
和他们相关Users
的给定seller
我认为这是您的存储库的一项工作,在您的情况下,它应该公开诸如 GetFullSeller (由 Include 加载的所有属性)和 GetSeller (仅基本实体)之类的方法。
编辑:
有多种方法可以在 EF v4 中加载导航属性。
没有自动加载。