이 관계를 사용하는 방식에 따라이를 구현하는 데는 여러 가지 방법이 있습니다. 서로 다른 구현과 관련된 성능 문제가 있습니다.
예를 들어 학부모, 형제, 아들 목록을 많이 쿼리해야하고이 데이터를 조금만 수정해야하는 경우 중복 된 정보를 저장할 수 있으므로 Sons/Parents 테이블과 Brothers 테이블이 있습니다. 이러한 관계에 대한 일부 EF 매핑이 있습니다. 이 테이블에는 관련 사용자의 기본 키만 저장되며 이러한 관계 중 하나 (예 : 새 아들 추가)를 수정할 때마다 여러 테이블에서 동일한 정보를 업데이트해야합니다.
그러나 데이터를 많이 수정하고 쿼리를 많이하지 않으면 상위 테이블 만 저장하는 것이 좋을 수 있습니다. 그러면 형제와 아들 목록이 다음과 같은 쿼리를 통해 유추 될 수 있습니다. 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"); });
}
마이그레이션이 테이블을 포함는 (I은 단순에 대한 ApplicationsUsers 엔티티의 정수 Id
속성을 추가) 이 표를 가지고 조금 놀아 라. 이를 통해 디버깅 할 경우 엔티티를 검사하고 Parents and Sons 목록의 내용을 검사 할 수 있습니다. TestContext
는 사용자에 대해 하나의 DbSet
을 포함
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");
}
}
public DbSet<ApplicationUser> Users { get; set; }
내가 예에서 형제 목록을 떠났다. EF는 Brothers 데이터를 Parents/Sons 데이터와 자동으로 동기화하지 않습니다. 따라서 부모/아들 목록에 추가 할 때 명시 적으로 사용자를 Brothers 목록에 추가해야합니다. 그러나 부모와 아들 목록은 자동으로 동기화됩니다. 사용자 A를 사용자 B의 부모 목록에 추가하고 데이터를 유지하면 사용자 B의 부모 목록에 사용자 A가 포함됩니다. 이는 부모와 아들의 매핑이 동일한 탐색 속성. 그것은 형제 재산과 함께 발생하지 않습니다.