我是一个流利的nHibernate新手,所以原谅我这很容易,我只是错过了它。
我有一个Customer和User的类层次结构,它们都继承自Person。客户和用户都有自己的表和映射,一切都很好。
我的问题是客户和用户需要有一个联系人列表,其类型为IList。因此,客户和用户都将拥有一个可以包含客户和用户组合的联系人列表。
我对如何映射这一点感到有点难过,并希望得到任何建议。
谢谢!
答案 0 :(得分:1)
我相信你需要一个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; }
}
解决问题的简单方法(hacky)将是一个鉴别器,并将所有内容移动到同一个表中。此映射可能如下所示:
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>
,但我相信你可以解决这个问题。 :)希望这有帮助!
答案 1 :(得分:0)
我是通过Party模型完成的。这样你的抽象总是派对:
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个表:派对,人员,组织和联系