これを実装するには、この関係を使用する方法に応じていくつかの方法があります。さまざまな実装に関連するパフォーマンスの問題があります。
たとえば、Parents、Brothers、Sonsのリストをすばやく検索する必要があり、これらのデータをほとんど変更する必要がない場合は、情報を重複して保存できるため、Sons/ParentsテーブルとBrothersテーブルがありますこれらの関係にはいくつかのEFマッピングがあります。これらのテーブルには、関係者の主キーのみが格納されます。これらの関係のいずれかを変更するたびに(たとえば、新しい息子を追加する場合)、複数のテーブルで同じ情報を更新する必要があります。
しかし、たくさんのデータを変更しなければならない場合は、Parentsテーブルのみを保存するほうが良いかもしれません。また、兄弟とSonsのリストは、 EFマッピングではなく、コードです。冗長テーブルと
例:これらのマッピングを使用:
CreateTable(
"dbo.ApplicationUsers",
c => new
{
Id = c.Int(nullable: false, identity: true),
FirstName = c.String(),
LastName = c.String(),
})
.PrimaryKey(t => t.Id);
CreateTable(
"dbo.Brothers",
c => new
{
Id = c.Int(nullable: false),
BrotherId = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.Id, t.BrotherId })
.ForeignKey("dbo.ApplicationUsers", t => t.Id)
.ForeignKey("dbo.ApplicationUsers", t => t.BrotherId)
.Index(t => t.Id)
.Index(t => t.BrotherId);
CreateTable(
"dbo.ParentsSons",
c => new
{
SonId = c.Int(nullable: false),
ParentId = c.Int(nullable: false),
})
.PrimaryKey(t => new { t.SonId, t.ParentId })
.ForeignKey("dbo.ApplicationUsers", t => t.SonId)
.ForeignKey("dbo.ApplicationUsers", t => t.ParentId)
.Index(t => t.SonId)
.Index(t => t.ParentId);
サンプル方法:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Parents).WithMany(u => u.Sons).Map(x => { x.MapRightKey("ParentId"); x.MapLeftKey("SonId"); x.ToTable("ParentsSons"); });
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Sons).WithMany(u => u.Parents);
modelBuilder.Entity<ApplicationUser>().HasMany(u => u.Brothers).WithMany().Map(x => { x.MapRightKey("BrotherId"); x.MapLeftKey("Id"); x.ToTable("Brothers"); });
}
移行がこれらのテーブルを(私は簡単にするためApplicationsUsersエンティティの整数Id
プロパティを追加)を含みますこれらのテーブルで少し演奏する。デバッグする場合は、エンティティを検査し、親と息子のリストの内容を確認することができます。 TestContext
は一つだけDbSet
ユーザーのために含まれていますpublic DbSet<ApplicationUser> Users { get; set; }
public void Test()
{
using (var context = new TestContext())
{
var arya = new ApplicationUser()
{
FirstName = "Arya",
Parents = new List<ApplicationUser>
{
new ApplicationUser { FirstName = "Eddard" },
new ApplicationUser { FirstName = "Catelyn" }
}
};
context.Users.Add(arya);
context.SaveChanges();
var eddard = context.Users.First(u => u.FirstName == "Eddard");
var jon = new ApplicationUser { FirstName = "Jon" };
eddard.Sons.Add(jon);
context.SaveChanges();
var eddardFromContext = context.Users.First(u => u.FirstName == "Eddard");
var catelynFromContext = context.Users.First(u => u.FirstName == "Catelyn");
}
}
私は例のうち、兄弟リストを残しました。 EFは自動的にBrothersデータをParents/Sonsデータと同期させないことに注意してください。したがって、Parents/Sonsリストに追加するときに、Brothersリストに明示的にユーザーを追加する必要があります。ただし、親と息子のリストは自動的に同期されます。ユーザーAをユーザーBの親リストに追加してデータを保持すると、ユーザーBの親リストにはユーザーAが含まれます。同じナビゲーションプロパティ。それはBrothersの財産では起こりません。