如何使用NHibernate(Fluent)映射此旧表?

如何使用NHibernate(Fluent)映射此旧表?,nhibernate,fluent-nhibernate,mapping,hierarchy,legacy,Nhibernate,Fluent Nhibernate,Mapping,Hierarchy,Legacy,NHibernate的新成员。我很难理解如何映射这个遗留表 CREATE TABLE [dbo].[CmnAddress]( [addressId] [int] NOT NULL, [objectType] [varchar](63) NULL, [objectId] [int] NULL, [addressType] [varchar](7) NULL, [recordStatus] [char](1) NULL, [fromDate] [int] NULL, [toDate] [int] N

NHibernate的新成员。我很难理解如何映射这个遗留表

CREATE TABLE [dbo].[CmnAddress](
[addressId] [int] NOT NULL,
[objectType] [varchar](63) NULL,
[objectId] [int] NULL,
[addressType] [varchar](7) NULL,
[recordStatus] [char](1) NULL,
[fromDate] [int] NULL,
[toDate] [int] NULL,
[onStreet] [varchar](254) NULL,
[atStreet] [varchar](254) NULL,
[unit] [varchar](30) NULL,
[city] [varchar](254) NULL,
[state] [varchar](30) NULL,
[zipCode] [varchar](30) NULL,
)
还有一个“CmnPerson”表,我已经映射到Person类。我需要Person类包含地址列表,其中objectType列包含“CmnPerson”,objectId字段与我的Person.Id(“CmnPerson.personId”)字段匹配

稍后我还要创建一个Contact类,该类还包含一个地址列表,其中objectType列包含“CmnContact”

我很难弄清楚我是否应该在子列上区分每个表使用任何映射或类层次结构?或者哪一个能满足我的需要

有人能告诉我如何映射这个地址类吗?流利的配置会更好

新增信息:

下面的类和映射几乎可以工作,但是地址列表返回CMNADRESS表中的所有行以及匹配的objectId,而不管objectType字段的值如何。我想我可以在HasMany映射上使用ApplyFilter来处理Person.Addresses,但这似乎不是“正确”的方法

更多添加信息:在调用DiscriminateSubClassesOnColumn(…)后,我始终将SelectWithValue()链接为on,从而解决了最后一个问题

公共类人物
{
公共虚拟整数Id{get;private set;}
公共虚拟字符串LastName{get;set;}
公共虚拟字符串FirstName{get;set;}
公共虚拟字符串MiddleName{get;set;}
公共虚拟字符串{get;set;}
公共虚拟IList PassClients{get;set;}
公共虚拟IList地址{get;set;}
}
公共类PersonMap:ClassMap
{
公众人物地图(){
表(“CmnPerson”);
Id(x=>x.Id).列(“personId”);
Map(x=>x.LastName);
Map(x=>x.FirstName);
Map(x=>x.MiddleName);
Map(x=>x.Gender);
HasMany(x=>x.PassClients).KeyColumn(“personId”);
有许多(x=>x.address);
}
}
抽象公共类地址
{
公共虚拟整数Id{get;private set;}
公共虚拟字符串StreetNo{get;set;}
树上的公共虚拟字符串{get;set;}
公共虚拟字符串单元{get;set;}
公共虚拟字符串City{get;set;}
公共虚拟字符串状态{get;set;}
公共虚拟字符串ZipCode{get;set;}
}
公共类PersonalAddress:地址{
公共虚拟人{get;set;}
}
公共类地址映射:类映射
{
公共地址映射(){
表格(“CMNADRESS”);
Id(x=>x.Id).列(“地址Id”);
地图(x=>x.StreetNo);
地图(x=>x.OnStreet);
Map(x=>x.Unit);
地图(x=>x.City);
Map(x=>x.State);
Map(x=>x.ZipCode);
DiscriminateSubClassesOnColumn(“对象类型”)。始终选择WithValue();
}
}
公共类PersonalAddressMap:子类映射
{
公众人物地址{
鉴别器值(“CmnPerson”);
引用(x=>x.Person)。列(“objectId”);
}
}
地址类

public class Address
{
    public virtual int Id { get; set; }
    public virtual Person Person { get; set; }
    // etc.
}
人类

public class Person
{
    public Person()
    {
        Addresses = new List<Address>();
    }

    public virtual int Id { get; set; }
    // etc.
    public virtual IList<Address> Addresses { get; set; }
}
公共类人物
{
公众人士()
{
地址=新列表();
}
公共虚拟整数Id{get;set;}
//等等。
公共虚拟IList地址{get;set;}
}
地址图

public class AddressMap : ClassMap<Address>
{
    public AddressMap()
    {
        Table("CmnAddress");
        Id(x => x.Id).Column("addressId");
        // etc.
        References(x => x.Person);
    }
}
公共类地址映射:类映射
{
公共地址映射()
{
表格(“CMNADRESS”);
Id(x=>x.Id).列(“地址Id”);
//等等。
参考文献(x=>x.Person);
}
}

要区分Address=>Person和Address=>Contact之间的差异,您需要阅读NHibernate的多态性,并根据列区分子类。

对不起,我不熟悉fluent映射,但是,一种方法是:

  • 创建一个地址抽象类,该类的属性对应于表中除对象类型之外的所有列
  • 创建一个扩展地址的PersonalAddress
  • 创建一个扩展地址的ContactAddress类

  • 以正常方式将CmnAddress的所有列映射到Address类的属性,声明为鉴别器列的objectType除外

  • 映射PersonalAddress作为Address的一个子类,具有鉴别器值“CmnPerson”
  • 映射联系人地址地址的子类,其鉴别器值为“CmnContact”

在代码中,Person类将保存一个PersonalAddress的列表,而Contact类将保存一个ContactAddress的列表

当Any映射是一个具有多个关系时,您不能使用它。当一个地址可以指向不同种类的对象时,比如一个人、一个订单或其他不相关的东西,就可以使用它

要映射层次结构,您可以这样做:

public class CmnAddressMap : ClassMap<CmnAddress>
{
    public CmnAddressMap()
    {
        Id(x => x.addressId);
        Map(x => x...);

        DiscriminateSubClassesOnColumn("objectType");
    }
}

public class PersonAdressMap : SubclassMap<PersonAddress>
{
    public PersonAdressMap()
    {
        DiscriminatorValue("objectType1");
    }
}

public class ContactAdressMap : SubclassMap<ContactAddress>
{
    public ContactAdressMap()
    {
        DiscriminatorValue("objectType2");
    }
}
public类CmnAddressMap:ClassMap
{
公共地图()
{
Id(x=>x.addressId);
Map(x=>x…);
DiscrimiteSubClasseSoncolumn(“对象类型”);
}
}
公共类映射:子类映射
{
公共地图()
{
鉴别器值(“objectType1”);
}
}
公共类ContactAddressMap:子类映射
{
公共联系人地址映射()
{
鉴别器值(“objectType2”);
}
}
有一个包含所有字段的抽象CmnAddress(例如映射CmnAdressMap中的所有字段)和两个名为PersonalAddress和ContactAddress的子类


然后这个人应该有一个像IList这样的集合,该集合应该映射为HasMany。你应该这样做。

这是我难以理解的区别部分。我不确定是否需要创建子类
public class CmnAddressMap : ClassMap<CmnAddress>
{
    public CmnAddressMap()
    {
        Id(x => x.addressId);
        Map(x => x...);

        DiscriminateSubClassesOnColumn("objectType");
    }
}

public class PersonAdressMap : SubclassMap<PersonAddress>
{
    public PersonAdressMap()
    {
        DiscriminatorValue("objectType1");
    }
}

public class ContactAdressMap : SubclassMap<ContactAddress>
{
    public ContactAdressMap()
    {
        DiscriminatorValue("objectType2");
    }
}