我是一位经验丰富的Web开发人员,拥有丰富的T-SQL和架构设计经验,但对于EF来说还是比较新的(直接跳到EF 6!)。我想知道我的POCO有什么问题,我正在为以下两个查询生成不同的SQL。
基本上,我有两个对象,“Parent”和“ChildThing”,具有1对多导航属性。这是“父”(自然键,未生成):
Public Class Parent
<Key>
<DatabaseGenerated(DatabaseGeneratedOption.None)> <MaxLength(10), MinLength(4)>
Public Property ParentCode As String
Public Property Description As String
' '''navigation property
Public Overridable Property ChildThings As ICollection(Of ChildThing) = New HashSet(Of ChildThing)
End Class
这是我的“ChildThing”
Public Class ChildThing
<Key, ForeignKey("Parent"), Column(Order:=10), DatabaseGenerated(DatabaseGeneratedOption.None), MaxLength(10), MinLength(4)>
Public Property ParentParentCode As String
<Key, Column(Order:=20), DatabaseGenerated(DatabaseGeneratedOption.None)>
Public Property DateEffective As Date
Public Property Price As Decimal
' '''Navigation Property: The 'parent' record associated with child
Public Overridable Property Parent As Parent
End Class
因此,如果我使用Parent的导航属性+ WHERE编写查询,请执行以下操作:
Dim effectiveDate As Date = DateTime.Parse("1/1/2015").Date
Dim parentObj = db.Parents().Find("7001")
Dim filteredPrices = From x In parentObj.ChildThings
Where x.DateEffective = effectiveDate
我得到filteredPrices
的sql似乎忽略了WHERE ..我的意思是,它有一个WHERE,但它只考虑了POCO模型中定义的FK: / p>
SELECT
[Extent1].[ParentParentCode] AS [ParentParentCode],
[Extent1].[DateEffective] AS [DateEffective],
[Extent1].[Price] AS [Price]
FROM [dbo].[ChildThings] AS [Extent1]
WHERE [Extent1].[ParentParentCode] = @EntityKeyValue1
如果我针对ChildThings直接构建的查询,
Dim filteredPrices = From x In db.ChildThings
Where x.ParentParentCode = "7001" AndAlso x.DateEffective = effectiveDate
然后,WHERE中有两个参数..
SELECT
[Extent1].[ParentParentCode] AS [ParentParentCode],
[Extent1].[DateEffective] AS [DateEffective],
[Extent1].[Price] AS [Price]
FROM [dbo].[ChildThings] AS [Extent1]
WHERE (N'7001' = [Extent1].[ParentParentCode]) AND ([Extent1].[DateEffective] = @p__linq__0)
感谢@MattBrooks结束我令人筋疲力尽的谷歌搜索。使用他提供的MSDN链接我能够得到以下解决方案(我必须关闭此导航集合属性的延迟加载)
Dim parentObj = db.Parents().Find("7001")
db.Entry(parentObj) _
.Collection(Function(x) x.ChildThings) _
.Query() _
.Where(Function(x) x.DateEffective = effectiveDate) _
.Load() 'extension meth. from System.Data.Entity
我一直在使用LINQ,只使用内存中的对象..从未使用过EF。我从调试中知道“扩展此节点将处理结果”或调用.ToList会导致集合被“处理”,并且我将这些概念投射到我的心理模型上,了解EF将如何执行查询。我仍然不清楚EF的所有魔法,但是,到那里。
答案 0 :(得分:3)
这是标准的EF行为。访问集合属性时,在为查询过滤结果之前,将所有相关实体从数据库延迟加载到集合中。在这种情况下,实际的过滤是由LINQ到对象而不是LINQ到实体执行的,正如您所期望的那样。
我发现这是过去有用的资源 - https://msdn.microsoft.com/en-gb/data/jj574232.aspx。它显示了一些通过集合属性有效查询相关实体的选项。