我使用的是代码优先实体框架方法,在我的OnModelCreating
函数中,我有以下代码:
With modelBuilder.Entity(Of FS_Item)()
.HasKey(Function(e) e.ItemKey)
.Property(Function(e) e.ItemRowVersion).IsConcurrencyToken()
.HasMany(Function(e) e.ItemInventories) _
.WithRequired(Function(e) e.Item).HasForeignKey(Function(e) e.ItemKey)
End With
在其他地方,我有一个Web API Get实现,其中包含一些诊断代码,我正在调试器中查看:
Public Function GetValue(ByVal id As String) As FS_Item
GetValue = If(data.FS_Item.Where(Function(i) i.ItemNumber = id).SingleOrDefault(), New FS_Item())
Dim c = GetValue.ItemInventories.Count
End Function
我希望c应该通过在FS_Iventory视图中查找ItemKey与检索到的FS_Item行的ItemKey匹配的行来获得一个非零值。但是我得到了0,即使有匹配的行。我是否正确呼叫.HasMany
、.WithRequired
和.HasForeignKey
?
注意,.WithRequired
对来自前一行的返回值进行操作,而其他行对With
块表达式进行操作。
编辑已请求FS_Item的此模型。这是:
Partial Public Class FS_Item
Public Property ItemNumber As String
Public Property ItemDescription As String
Public Property ItemUM As String
Public Property ItemRevision As String
Public Property MakeBuyCode As String
' Many many more properties
Public Property ItemRowVersion As Byte()
Public Property ItemKey As Integer
Private _ItemInventories As ICollection(Of FS_ItemInventory) = New HashSet(Of FS_ItemInventory)
Public Overridable Property ItemInventories As ICollection(Of FS_ItemInventory)
Get
Return _ItemInventories
End Get
Friend Set(value As ICollection(Of FS_ItemInventory))
_ItemInventories = value
End Set
End Property
End Class
编辑学到了一些有趣的东西。如果我将Dim c = GetValue.ItemInventories.Count
更改为:
Dim c = data.FS_ItemInventory.ToList()
Dim correctCount = GetValue.ItemInventories.Count
然后correctCount得到值3。这就像它了解对象之间的关联,但不了解如何自动查询它们,因为我习惯于从LINQ到SQL。EF在这方面有什么不同吗?
编辑我已经确定可以使用以下显式加载代码加载关联的对象:
data.Entry(GetValue).Collection(Function(e) e.ItemInventories).Load()
我现在想了解的是,究竟是什么决定了实体是否会延迟加载?从我所能发现的所有迹象来看,它应该是懒洋洋地装载的。我甚至尝试将ItemInventory的声明更改为此,但在尝试访问它时遇到了NullReferenceException:
Public Overridable Property ItemInventories As ICollection(Of FS_ItemInventory)
事实证明,我认为不相关的代码禁用了延迟加载。我在FSDB的构造函数中有这个:
DirectCast(Me, IObjectContextAdapter).ObjectContext.ContextOptions.ProxyCreationEnabled = False
感谢EF 4-懒惰加载没有代理,我看到这也将禁用懒惰加载。添加代码的原因是由于另一个错误:
类型'System.Data.Entity.DynamicProxies.FS_Item_6415A45C642902D6044AFA1AFD239E7DCB82FD000A10FE4F8DE6EA26A2AB418'具有数据协定名称'FS_Item_64115A45C642902D6044AFA1AFD239E7DCB82FD000A10FE4F8DE6EA26A2AB418:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies'不应为。考虑使用DataContractResolver或添加已知类型列表中静态未知的类型-例如,通过使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型的列表。
根据具有一对多关系的实体框架对象的序列化,简单的解决方案是禁用代理。