来自我的另一个实体框架(ADO.NET)问题。 我正在使用EF1(没有选择)并且有一个MySQL数据库作为后端。
一个简单的问题我无法真正找到令人满意的答案:
我到底需要做什么才能加载? IE。,当我有一个实体并希望通过它的孩子进行枚举时,说我有实体“组”并且它有一个孩子“用户”,我想做“从n in g.Users,其中n.UserID = 4选择n“,我首先要调用g.Users.Load();
这有点烦人,因为当我对一个未加载的集合进行查询时,我会期望EF自动加载它 - 至少抛出一些异常,而不是简单地返回0结果?
我需要照顾装载的另一个案例: 我有一个问题:
from n in Users where n.Group.Name == "bla" select n
由于某种原因,它失败了,为n.Group提供了一个空指针,即使正确设置了n.GroupID(该组的键)。此外,当我之前做Server.Groups.Load()(组是一个服务器的子组)时,它可以工作。
是否有关于何时调用哪个集合的Load()的确切政策?
再次感谢你, 迈克尔
答案 0 :(得分:2)
第一版实体框架中没有延迟加载。每当您想要访问之前未加载的内容时,无论是对单个对象还是对象集合的引用,您都必须明确告诉它加载该引用。 Include()选项(首先来自Rup)将尝试在一个大型查询和处理调用中加载您想要的所有数据,结果是Include()执行缓慢。另一种方法(来自Rup的第二个方法),检查然后加载卸载的引用,执行得更快,并允许我们将负载限制为我们需要的。
基本上我们的政策是只加载您在初始查询中所拥有的内容,从而最大限度地降低性能影响。然后,当我们想要访问引用的实体或实体集合时,我们将检查并加载引用。这导致了对数据库的更多查询,但它们更快,我们只在需要时加载辅助数据,而不是预先加载我们可能需要的所有内容。可能会在函数中多次检查相同的属性,但它只会被加载一次,我们可以确定我们只是加载它,因为我们正在使用它。
答案 1 :(得分:1)
您的意思是ObjectQuery.Include,例如
var g = from g in MyDb.Groups.Include("Users") where g.Id = 123 select g;
from n in g.Users where n.UserID = 4 select n
from n in Users.Include("Group") where n.Group.Name == "bla" select n
如果您担心过度使用它们,也可以将Load()
包裹在支票中,
if (g.CanLoadReferences() && !g.Users.IsLoaded)
{
g.Users.Load();
}
(对于任何愚蠢的语法滑倒道歉 - 我现在使用其他LINQ语法和EF4)
答案 2 :(得分:0)
当我们针对MS SQL服务器运行时,这可能是MySQL适配器中的限制。
您使用的是最新版本6.2.3吗?请参阅:http://www.mysql.com/downloads/connector/net