我有一个名为 WidgetCollection 的类。它有一个 Items 属性公开一个 List(Of Widget) 和一个 SelectedWidget 属性。我希望EF按如下方式构建数据库:
- 在我的 Widgets 表中添加一个 WidgetCollection_Id 属性,指定每个小部件所在的 WidgetCollection
- 在我的 WidgetCollection 表中添加 SelectedWidget_Id 属性,指定选择哪个 Widget
- 添加从 WidgetCollection.Id 到 Widget.WidgetCollection_Id 的一对多关系
- 添加从 Widget.Id 到 WidgetCollection.SelectedWidget_Id 的 1 对 0 或 1 关系
我可以确认它似乎确实正确地构建了数据库模式,但是如果我在分配给 SelectedWidget 后保存了上下文,则会收到以下错误:
System.Data.Entity.Infrastructure.DbUpdateException 发生 HResult=-2146233087 消息=保存不公开外键 > 关系属性的实体时发生错误。EntityEntries 属性将返回 null,因为无法将单个实体标识为异常源。通过在实体类型中公开外键属性,可以更轻松地处理保存时的异常。
除了内部的例外
无法确定相关操作的有效排序。由于外键约束、模型要求或存储生成的值,可能存在依赖关系。
我可以通过从不分配 WidgetCollect.SelectedWidget 来防止此错误。
我想问题在于 EF 无法弄清楚如何处理两个方向的关系,但我就是找不到将其指向正确方向的方法。示例代码如下,欢迎所有建议!
Public Class Widget
Private miId As Integer
Public Property Id As Integer
Get
Return miId
End Get
Set(value As Integer)
miId = value
End Set
End Property
Private msName As String
Public Property Name As String
Get
Return msName
End Get
Set(value As String)
msName = value
End Set
End Property
End Class
Public Class WidgetCollection
Private miId As Integer
Public Property Id As Integer
Get
Return miId
End Get
Set(value As Integer)
miId = value
End Set
End Property
Private msName As String
Public Property Name As String
Get
Return msName
End Get
Set(value As String)
msName = value
End Set
End Property
Private moSelectedWidget
Public Property SelectedWidget As Widget
Get
Return moSelectedWidget
End Get
Set(value As Widget)
moSelectedWidget = value
End Set
End Property
Private moWidgets As New List(Of Widget)
Public Property Widgets As List(Of Widget)
Get
Return moWidgets
End Get
Set(value As List(Of Widget))
moWidgets = value
End Set
End Property
End Class
Public Class MyContext
Inherits DbContext
Public Property Widgets As DbSet(Of Widget)
Public Property WidgetCollections As DbSet(Of WidgetCollection)
End Class
Class Application
Public Sub New()
Database.DefaultConnectionFactory = New SqlCeConnectionFactory("System.Data.SqlServerCe.4.0", "", "Data Source=\EFtest.sdf")
Database.SetInitializer(New DropCreateDatabaseIfModelChanges(Of MyContext))
Dim oContext = New MyContext
Dim oWidgetA = New Widget With {.Name = "Widget A"}
Dim oWidgetB = New Widget With {.Name = "Widget A"}
Dim oWidgetCollection = New WidgetCollection With {.Name = "My widget collection"}
oWidgetCollection.Widgets.Add(oWidgetA)
oWidgetCollection.Widgets.Add(oWidgetB)
oWidgetCollection.SelectedWidget = oWidgetA 'Removing this line prevents error
oContext.WidgetCollections.Add(oWidgetCollection)
oContext.SaveChanges()
End Sub
End Class