- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
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/
你能比较一下属性吗 我想禁用文本框“txtName”。有两种方式 使用javascript,txtName.disabled = true 使用 ASP.NET, 哪种方法更好,为什么? 最佳答案 我
Count 属性 返回一个集合或 Dictionary 对象包含的项目数。只读。 object.Count object 可以是“应用于”列表中列出的任何集合或对
CompareMode 属性 设置并返回在 Dictionary 对象中比较字符串关键字的比较模式。 object.CompareMode[ = compare] 参数
Column 属性 只读属性,返回 TextStream 文件中当前字符位置的列号。 object.Column object 通常是 TextStream 对象的名称。
AvailableSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。 object.AvailableSpace object 应为 Drive 
Attributes 属性 设置或返回文件或文件夹的属性。可读写或只读(与属性有关)。 object.Attributes [= newattributes] 参数 object
AtEndOfStream 属性 如果文件指针位于 TextStream 文件末,则返回 True;否则如果不为只读则返回 False。 object.A
AtEndOfLine 属性 TextStream 文件中,如果文件指针指向行末标记,就返回 True;否则如果不是只读则返回 False。 object.AtEn
RootFolder 属性 返回一个 Folder 对象,表示指定驱动器的根文件夹。只读。 object.RootFolder object 应为 Dr
Path 属性 返回指定文件、文件夹或驱动器的路径。 object.Path object 应为 File、Folder 或 Drive 对象的名称。 说明 对于驱动器,路径不包含根目录。
ParentFolder 属性 返回指定文件或文件夹的父文件夹。只读。 object.ParentFolder object 应为 File 或 Folder 对象的名称。 说明 以下代码
Name 属性 设置或返回指定的文件或文件夹的名称。可读写。 object.Name [= newname] 参数 object 必选项。应为 File 或&
Line 属性 只读属性,返回 TextStream 文件中的当前行号。 object.Line object 通常是 TextStream 对象的名称。 说明 文件刚
Key 属性 在 Dictionary 对象中设置 key。 object.Key(key) = newkey 参数 object 必选项。通常是 Dictionary 
Item 属性 设置或返回 Dictionary 对象中指定的 key 对应的 item,或返回集合中基于指定的 key 的&
IsRootFolder 属性 如果指定的文件夹是根文件夹,返回 True;否则返回 False。 object.IsRootFolder object 应为&n
IsReady 属性 如果指定的驱动器就绪,返回 True;否则返回 False。 object.IsReady object 应为 Drive&nbs
FreeSpace 属性 返回指定的驱动器或网络共享对于用户的可用空间大小。只读。 object.FreeSpace object 应为 Drive 对象的名称。
FileSystem 属性 返回指定的驱动器使用的文件系统的类型。 object.FileSystem object 应为 Drive 对象的名称。 说明 可
Files 属性 返回由指定文件夹中所有 File 对象(包括隐藏文件和系统文件)组成的 Files 集合。 object.Files object&n
我是一名优秀的程序员,十分优秀!