유창한 nhibernate에서 기본 클래스 목록을 저장합니다
-
05-07-2019 - |
문제
나는 약간의 유창한 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 개의 테이블을 만들어야합니다.