gpt4 book ai didi

c# - Entity Framework 5(代码优先)导航属性

转载 作者:太空宇宙 更新时间:2023-11-03 11:12:12 25 4
gpt4 key购买 nike

Entity Framework 在查询/过滤之前为导航属性加载具有给定外键的所有项目是否正确?

例如:

myUser.Apples.First(a => a.Id == 1 && !a.Expires.HasValue);

将加载与该用户关联的所有苹果。 (SQL 查询不查询 ID 或 Expires 字段)。

还有其他两种方法(生成正确的 SQL),但都没有使用导航属性那么干净:

myDbContext.Entry(myUser).Collection(u => u.Apples).Query().First(a => a.Id == 1 && !a.Expires.HasValue);

myDbContext.Apples.First(a => a.UserId == myUser.Id && a.Id == 1 && !a.Expires.HasValue);

我检查过的东西

  • 延迟加载已启用且未在任何地方禁用。
  • 导航属性是虚拟的

最佳答案

编辑:

好的,根据您的编辑,我认为我对您的要求有错误的想法(现在更有意义了)。我将保留之前的答案,因为我认为它可能有助于解释,但与您目前的具体问题的相关性要小得多。

根据您发布的内容,您的用户对象已启用延迟加载。 EF 默认启用延迟加载,但是延迟加载有一项要求,即将导航属性标记为虚拟(您已完成)。

延迟加载的工作原理是附加到导航属性上的 get 方法,并在该点执行 SQL 查询以检索外部实体。导航属性也不是可查询的集合,这意味着当您执行 get 方法时,您的查询将立即执行。

在您上面的示例中,在您执行 .first 调用之前枚举了 User 上的 apples 集合(使用普通的旧 linq to objects 发生)。这意味着 SQL 将返回与用户关联的所有苹果,并在查询机器的内存中过滤它们(正如您所观察到的)。这也意味着您需要两个查询来提取您感兴趣的苹果(一个用于用户,一个用于 nav 属性),如果您只想要苹果,这对您来说可能效率不高。

也许更好的方法是将整个表达式作为查询尽可能长时间地保留。这方面的一个例子如下所示:

myDbContext.Users
.Where(u=>u.Id == userId)
.SelectMany(u=>u.Apples)
.Where(a=>a.Id == 1 && !a.Expires.HasValue);

这应该作为单个 SQL 语句执行,并且只会拉下您关心的苹果。

HTH


好的,根据我对您问题的理解,您问的是为什么 EF 似乎允许您在查询中使用导航属性,即使它们在结果集中可能为 null。

在回答您的问题时,是的,这是预期的行为,原因如下:

为什么你写一个查询它被翻译成SQL,例如像

myDbContext.Apples.Where(a=>a.IsRed)

会变成类似的东西

Select * from Apples
where [IsRed] = 1

类似下面这样的也会被直接翻译成SQL

myDbContext.Apples.Where(a=>a.Tree.Height > 100)

会变成类似的东西

Select a.* from Apples as a
inner join Tree as t on a.TreeId = t.Id
where t.Height > 100

然而,当我们实际提取结果集时,情况就有点不同了。

为避免提取过多数据并使其变慢,EF 提供了多种机制来指定结果集中返回的内容。一个是延迟加载(如果你想避免性能问题,需要小心使用),第二个是 include 语法。这些方法限制了我们撤回的内容,以便查询快速并且不会消耗不需要的资源。

例如,在上面的示例中,您会注意到仅返回 Apple 字段。

如果我们向其中添加一个包含,如下所示,您可能会得到不同的结果:

myDbContext.Apples.Include(a=>a.Tree).Where(a=>a.Tree.Height > 100)

将转换为类似以下的 SQL:

Select a.*, t.* from Apples as a
inner join Tree as t on a.TreeId = t.Id
where t.Height > 100

在你上面的例子中(我相当确定它在语法上不正确,因为 myContext.Users 应该是一个集合,因此不应该有一个 .Apples)你正在创建一个查询,所有变量都可用。当您枚举该查询时,您必须明确返回的内容。

有关导航属性及其工作方式(以及 .Include 语法)的更多详细信息,请查看我的博客:http://blog.staticvoid.co.nz/2012/07/entity-framework-navigation-property.html

关于c# - Entity Framework 5(代码优先)导航属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13575760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com