WidgetCollection というクラスがあります。List(Of Widget) と SelectedWidget プロパティを公開する Items プロパティがあります。私は、EF が次のようにデータベースを構築することを期待しています。
- Widgets テーブルに WidgetCollection_Id プロパティを追加し、各ウィジェットがどの WidgetCollection にあるかを指定します
- WidgetCollection テーブルに SelectedWidget_Id プロパティを追加し、どのウィジェットを選択するかを指定します
- WidgetCollection.Id から Widget.WidgetCollection_Id に 1 対多の関係を追加します。
- Widget.Id から WidgetCollection.SelectedWidget_Id に 1 対 0 または 1 の関係を追加します。
データベース スキーマが正しく構築されているように見えることは確認できますが、SelectedWidget に割り当てた後にコンテキストを保存すると、次のエラーが発生します。
System.Data.Entity.Infrastructure.DbUpdateException が発生しました HResult=-2146233087 Message=関係の外部キー > プロパティを公開しないエンティティの保存中にエラーが発生しました。単一のエンティティを例外のソースとして識別できないため、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