문제

나는 약간의 유창한 nhibernate 초보자이므로 용서하는 것이 쉽다는 것을 용서합니다.

고객과 사용자와 함께하는 클래스 계층 구조가 있습니다. 고객과 사용자는 각각 고유 한 테이블과 매핑을 가지고 있으며 모든 것이 잘 작동합니다.

내 문제는 고객과 사용자가 연락처 목록이 있어야한다는 것입니다. 따라서 고객과 사용자는 각각 고객과 사용자를 혼합 할 수있는 연락처 목록이 있습니다.

나는 이것을 매핑하는 방법에 대해 약간 혼란스럽고 제공되는 조언에 감사 할 것입니다.

감사!

도움이 되었습니까?

해결책

나는 당신이 필요하다고 생각합니다 IList<Person> Contacts {get;set;} 그리고 유형 (판별 자)을 통해 무엇을 캐스팅 해야하는지 알 수 있습니다. 어쩌면 해킹일지도 모르지만 그게 내가 할 수있는 방법입니다.

편집 : 엔티티가 아래에서 보일 것이라고 가정 해 봅시다.

public abstract class Person
{
    public virtual int Id { get; private set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

public class Customer : Person
{
    public virtual string Foo { get; set; }
}

public class Contact : Person
{
    public virtual string Bar { get; set; }
}

문제를 해결하는 쉬운 (해킹) 방법은 판별자가되며 모든 것을 동일한 테이블로 옮깁니다. 이에 대한 매핑은 다음과 같습니다.

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.Id).GeneratedBy.Native();
        Map(x => x.FirstName).Length(40);
        Map(x => x.LastName).Length(100);
        DiscriminateSubClassesOnColumn("TypeOfPerson");
    }
}

public class CustomerMap : SubclassMap<Customer>
{
    public CustomerMap()
    {
        Map(x => x.Foo);
    }
}

public class ContactMap : SubclassMap<Contact>
{
    public ContactMap()
    {
        Map(x => x.Bar);
    }
}

해당 모델을 기반으로 스키마를 생성하면 다음으로 끝납니다.

create table [Person] (
  Id                 INT   IDENTITY   NOT NULL,
  BillingDetailsType NVARCHAR(255)   not null,
  FirstName          NVARCHAR(40)   null,
  LastName           NVARCHAR(100)   null,
  Foo                NVARCHAR(255)   null,
  Bar                NVARCHAR(255)   null,
    primary key ( Id ))

나는 당신의 상사 (나의 것과 같은)가 데이터베이스를 그러한 상태로 떠나기를 거부하는 데이터베이스 전문가라면 이것이 이상적이지 않다는 것을 이해합니다. 그러면 당신이해야 할 일은 DiscriminateSubClassesOnColumn("TypeOfPerson"); 대신 코드에서 스키마를 생성하는 경우 아래와 같은 테이블 구조로 끝나야합니다.

-- statement #1
create table [Person] (
  Id        INT   IDENTITY   NOT NULL,
  FirstName NVARCHAR(40)   null,
  LastName  NVARCHAR(100)   null,
    primary key ( Id ))

-- statement #2
create table [Customer] (
  Person_id INT   not null,
  Foo       NVARCHAR(255)   null,
    primary key ( Person_id ))

-- statement #3
create table [Contact] (
  Person_id INT   not null,
  Bar       NVARCHAR(255)   null,
    primary key ( Person_id ))

-- statement #4
alter table [Customer]
 add constraint FKFE9A39C0B58BA2A5 foreign key ( Person_id ) references [Person]

이 마지막 스키마를 사용하면 선택한 사람이 실제로 어떤 서브 클래스인지 결정하는 방법을 찾아야합니다. IList<Person> 그러나 나는 당신이 그것을 알아낼 수 있다고 확신합니다. :) 도움이 되었기를 바랍니다!

다른 팁

나는 파티 모델로 이것을했다. 이런 식으로 당신의 추상화는 항상 파티입니다.

public abstract class Party
{
     private IList<Party> _contacts = new List<Party>();

     public int Id {get; set;}
     public abstract string DisplayName { get; }
     public IEnumerable<Party> Contacts { get { return _contacts; } }  
}

public class Person 
{
     public string FirstName {get; set;}
     public string LastName {get; set;}

     public override string DisplayName 
     {
         get { return FirstName + " " + LastName; }
     }
}

public class Organization
{
     public string Name {get; set;}

     public override string DisplayName 
     {
         get { return Name; }
     }
}

매핑하려면 두 가지 가능한 전략이 있습니다 : 상속 트리 당 하나의 테이블; 수업 당 하나의 테이블.

public class PartyMap : ClassMap<Party>
{
    public PartyMap()
    {
        Id(x => x.Id).GeneratedBy.Native();
        HasManyToMany(x => x.Contacts).Access.CamelCaseField(Prefix.Underscore);
    }
}

public class PersonMap : JoinedSubClassPart<Person>
{
    public PersonMap()
    {
        Map(x => x.FirstName).Length(40);
        Map(x => x.LastName).Length(100);
    }
}

public class OrganizationMap : JoinedSubClassPart<Organization>
{
    public OrganizationMap()
    {
        Map(x => x.Name).Length(40);
    }
}

파티, 사람, 조직 및 연락처 4 개의 테이블을 만들어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top