この質問は以前にもあったと思いますので、あらかじめお詫び申し上げますが、検索に含める正しいキーワードがわかりません...
オブジェクトのプロパティの 1 つが切断された環境 (Web サイトなど) の他のプロパティのコレクションである場合、オブジェクトを更新 (または挿入) するための適切なパターンを理解するのに苦労しています。私の問題は、Web アプリケーションが完全なオブジェクトではなく、ID のコレクションのみを返すという考えに関係しています。これを説明する最善の方法は、コード スニペットを使用することだと思います。
次のオブジェクトが与えられた場合
Public Class User
Public Property UserId As Integer
Public Property Username As String
Public Property Roles As ICollection(Of Role)
End Class
Public Class Role
Public Property RoleId As Integer
Public Property RoleName As String
Public Property Users As ICollection(OF User)
End Class
Public Class EFDbContext
Inherits Entity.DbContext
Public Property Users As Entity.DbSet(Of User)
Public Property Roles As Entity.DbSet(Of Role)
End Class
データベースは、Users、Roles、および RoleUsers の 3 つのテーブルで作成されます。
私は簡単に次のことができることを知っています
Dim db = New EFDbContext()
Dim r1 = New Role() With { .RoleName = "User" }
Dim r2 = New Role() With { .RoleName = "Admin" }
db.Roles.Add(r1)
db.Roles.Add(r2)
Dim u1 = New User() With { .UserName = "test1", .Roles = New List(Of Role) }
u1.Roles.Add(r1)
db.Users.Add(u1)
db.SaveChanges()
そして、両方の新しい役割をデータベースに保存し (RoleId の値をそれぞれ 1 と 2 に設定)、新しいユーザー (UserId の値に 1 を設定)、および RoleId 1 と UserId 1 の新しい Role-User エントリを保存します。
ただし、Web サイトのような接続されていないシナリオを扱う場合、ほとんどの人はビュー モデルを使用してユーザーからの入力を表し、エンティティにマップし直します。さらに、役割を表す値の場合、返されるデータには、役割を表す一意のキーのみが含まれる可能性が高くなります。例えば、
Public Class UpdatedUserViewModel
Public Property UserId As Integer
Public Property Username As String
Public Property RoleIds As ICollection(Of Integer)
End Class
...
...
Dim userEntity = db.Users.Find(user.Values.UserId)
AutoMapper.Mapper.Map(userValues, userEntity)
したがって、userEntity.Roles コレクションには 1 つのアイテムが含まれている可能性がありますが、マッパーはおそらく次のようなエントリを追加しただけです。
ForMember(Function(u) u.Roles, Sub(m) m.MapFrom(Function(su) su.RoleIds.Select(Function(r) New Role() With {.RoleId = r})))
ここで問題が発生します。SaveChanges()
メソッドが呼び出されると、.RoleName プロパティが Nothing であるため、EF は検証エラーをスローします。
この状況はどのように処理されますか? ロールを手動でループして、データベースからそれぞれをフェッチする必要がありますか? マッピング ツールを使用できないのですか? 「欠落している」プロパティに偽の値を指定してから、ループしてそれらを Unchanged としてマークしますか?
これが長いことはわかっていますが、ウォークスルーが役立つと思いました...
ありがとう。