0

다음과 같이 Organization 클래스와 User 클래스가 있습니다. & 두 개의 개별적인 many-to-many를 필요로하지 않고 각 개별적으로 Address를 할당 할 수 있기를 원합니다. AddressUser에 대한 테이블 & AddressOrganization, AddressAnything, 등등. 이유는 내가 주소를 할당하고자하는 여러 엔티티가 &에있을 때 주소 레코드가 필요한 모든 단일 엔티티에 대한 중간 조인 테이블을 원하지 않기 때문입니다.일반 오브젝트 유형의 Fluent API 복합 외래 키

관련 주소가 필요한 각 엔티티에 대해 Address.OrganizationId 또는 Address.UserId와 같은 외래 키를 저장하고 싶지 않습니다.

Fluent API 또는 Code-First Data Annotation은 객체 유형이있는 일종의 복합 일반 외래 키를 수용 할 수 있습니까?

DomainObjectType 테이블과 비슷합니까?

DomainObjectType :

public class DomainObjectType 
{ 
    [Key] 
    public int Id { get; set; } // seeded 

    public string ObjectType { get; set; } // User or Organization 
} 

DomainObjectType 함께 시드 할 것 :

var objTypes = new List<DomainObjectType> 
    { 
     new DomainObjectType() { Id = 1, ObjectType = "User" }, 
     new DomainObjectType() { Id = 2, ObjectType = "Organization" } 
    }; 
objTypes.ForEach(c => context.DomainObjectTypes.Add(c)); 
context.SaveChanges(); 

조직 :

public class Organization 
    {  
     // Primary key 
     [Key] 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public string Description { get; set; } 

     #region Navigation Properties 

     public virtual ICollection<User> Users { get; set; } 
     public virtual ICollection<Address> Addresses { get; set; } 

     #endregion 

    } 

사용자

public class User 
{ 
    [Key] 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int OrganizationId { get; set; } 

    [ForeignKey("OrganizationId")] 
    public virtual Organization Organization { get; set; } 
    public virtual ICollection<Address> Addresses { get; set; } 
} 

주소

public class Address 
{ 
    // Primary Key 
    public int Id { get; set; } 
    public string Address1 { get; set; } 
    public string Address2 { get; set; } 
    public string City { get; set; } 
    public string State { get; set; } 
    public string Zip { get; set; } 
    public string AddressType { get; set; } 

    #region Foreign Keys 

    // not completely sure about this? (maybe move to many-to-many "join" table) 
    public int DomainObjectId { get; set; } // Composite key; would be either an OrganizationId or UserId 
    public string DomainObjectTypeId { get; set; } // Composite key 

    #endregion 

    #region Navigation Properties 

    public virtual ICollection<Organization> Organizations { get; set; } 
    public virtual ICollection<User> Users { get; set; } 

    #endregion 

} 

유창함 API 물건 :

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Configure Code First to ignore PluralizingTableName convention 
     // If you keep this convention then the generated tables will have pluralized names. 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 

     // one-to-many Organization-to-Users 
     modelBuilder.Entity<User>() 
      .HasRequired(u => u.Organization) 
      .WithMany(o => o.Users) 
      .HasForeignKey(u => u.OrganizationId); 

     // what goes here for generic AddressDomainObjectType? 
    } 
+0

'Address'와'User'와'Address'와'Organization' 사이에 다 대다 관계가 있습니까? 처음에는 그렇게 말했지만 모델 스케치는 다 대다 (many-to-many)처럼 보이지 않습니다. – Slauma

+0

당신의 모델은 @Slauma가 말한 것처럼 혼란 스럽 습니다만, 여러분의'Address' 테이블에 대해 다음과 같은'.HasForeignKey (i => new {i.DomainObjectId, i.DomainObjectTypeId})'가 필요할지도 모릅니다. – NSGaga

+0

내 사용자 및 주소 클래스를 수정하여 다 대다를 나타냅니다. 그것은 결국 many - to - many를 필요로 할 것 같습니다 - AddressDomainObjectType? – woodyiii

답변

1

당신은 당신이 원하는 것을 얻을 수 있습니다 - 단 하나의 여러 대를 가지고 Address과 "o THER 실체 "- 사람들을 위해 기본 클래스를 생성하여"다른 엔티티 ", 예를 들어 : 유창함 API와

public abstract class DomainObjectWithAddresses 
{ 
    public int Id { get; set; } 

    public virtual ICollection<Address> Addresses { get; set; } 
} 

public class User : DomainObjectWithAddresses 
{ 
    // other properties but without Id which is inherited from base class 
} 

public class Organization : DomainObjectWithAddresses 
{  
    // other properties but without Id which is inherited from base class 
} 

public class Address 
{ 
    public int Id { get; set; } 
    // other properties 

    public virtual ICollection<DomainObjectWithAddresses> DomainObjects 
                   { get; set; } 
} 

매핑 :

modelBuilder.Entity<DomainObjectWithAddresses>() 
    .HasMany(d => d.Addresses) 
    .WithMany(a => a.DomainObjects) 
    .Map(x => 
    { 
     x.ToTable("DomainObjectAddresses"); 
     x.MapLeftKey("DomainObjectId"); 
     x.MapRightKey("AddressId"); 
    }); 

modelBuilder.Entity<User>() 
    .ToTable("Users");   // TPT inheritance mapping 

modelBuilder.Entity<Organization>() 
    .ToTable("Organizations"); // TPT inheritance mapping 

귀하의 DbContext은 기본 유형에 대한 DbSet 있습니다

public DbSet<DomainObjectWithAddresses> DomainObjects { get; set; } 

나는 그것을 좋아하지 않는다. 주소와 다 대다 관계를 갖는 모든 유형에 대해 여러 조인 테이블을 도입하는 것을 선호합니다. 데이터베이스의 일부 테이블을 저장하기 위해서만 도메인 모델에 추상화를 도입하는 것이 좋습니다. 이 추상 DomainObjectWithAddresses 클래스는 도메인 모델에서 중요한 의미가없는 매우 기술적 인 (테이블 절약 도우미) 아티팩트입니다.나에게는 사용자 주소를 가지고 있으며, 조직 주소 대신 사용자 주소를 가진 개체라고 말을 가지고 조직 주소를 가진 개체라고 말을 훨씬 더 자연스러운 소리. 장기적으로 이것은 모델 작업을 복잡하게 할뿐입니다.

+0

당신은 내 문제를 해결했지만 다른 방향으로 나를 조종했습니다. 와우, 정직한 관찰에 감사드립니다. 기술적으로 달성 할 수 있다고해도 내가 여기에있는 것들을 복잡하게 만드는 것처럼 느껴지기를 동의한다. 나는 당신의 대답을 받아 들일 것이지만 여분의 다중 조인 테이블을 가지고 간다. – woodyiii

+0

기존 엔티티에 대해 동일한 기본 클래스를 수행하려고했는데 (기존 데이터베이스로 작업 할 때 추가로 복잡함이 있음), 훨씬 자연스러운 디자인이 Address 유형을 UserAddress 및 OrganizationAddress와 같은 하위 유형으로 분리한다는 것을 깨달았습니다. . 내 솔루션을 참조하십시오 http://stackoverflow.com/questions/38275335/polymorphic-associations-in-entity-framework/38287144#38287144 (이 질문은 오래된 것으로 알고 있지만 다른 사람이 할 수 있음) – drizin