流畅的NHibernate在一个表中映射多个模型

时间:2013-11-25 12:08:17

标签: asp.net asp.net-mvc nhibernate fluent-nhibernate fluent-nhibernate-test

我目前使用表来存储两种不同类型的实体,并使用表intTypeId中的列来区分它们

实体公司:

       public CompanyMap
       {
            Table("tblTable");
            Id(x => x.Id, "intId");
            Map(x => x.TypeId, "intTypeId");
            Map(x => x.Name, "strCompanyName");
            ...
       }

实体人:

       public PersonMap
       {
            Table("tblTable");
            Id(x => x.Id, "intId");
            Map(x => x.TypeId, "intTypeId");
            Map(x => x.Name, "strPersonName");
            ...
       }

我将这两个模型映射到一个表中,它似乎在网页上运行良好,但它打破了一些持久性规范测试,抛出异常。

公司的测试表明,"strPersonName"列不能是NULL,而人员的测试表明列"strCompanyName"不能是NULL。如果我删除这两个中的任何一个地图,测试就会通过。

你能告诉我为什么会这样吗?

2 个答案:

答案 0 :(得分:1)

有一种方法可以使用鉴别器列来完成此操作,在这种情况下,您可以使用基类来映射所有常用列,例如:

public class TableMap : ClassMap<Table>
{    
   public TableMap()
   {
      Table("tblTable");

      Id(x => x.Id, "intId");

      // here we specify the name of the column for discriminate types
      DiscriminateSubClassesOnColumn("intTypeId").Not.Nullable();

      Map(x => x.Name, "strCompanyName");      
      // other columns...
   }
}

之后,您只需为每个实体使用SubclassMap<T>实现映射,以获取示例:

public class CompanyMap : SubclassMap<Company>
{
   public CompanyMap()
   {
       DiscriminatorValue(@"Company");  // value for discriminator column
   }
}

public class PersonMap : SubclassMap<Person>
{
   public PersonMap()
   {
       DiscriminatorValue(@"Person");  // value for discriminator column
   }
}

看看这篇文章: http://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat

答案 1 :(得分:1)

根据this answer,我会尝试使用Fluent NH过滤器

假设CompanyintTypeId=1PersonintTypeId=2,您可以定义两个过滤器类:

public class PersonConditionFilter : FilterDefinition
{
    public PersonConditionFilter()
    {
        WithName("PersonCondition").WithCondition("intTypeId=2");
    }
}

public class CompanyConditionFilter : FilterDefinition
{
    public CompanyConditionFilter()
    {
        WithName("CompanyCondition").WithCondition("intTypeId=1");
    }
}

然后你会在映射中使用这些过滤器:

 public PersonMap()
{
    Table("tblTable");
    Id(x => x.Id, "intId");
    Map(x => x.TypeId, "intTypeId");
    Map(x => x.Name, "strPersonName");
    ApplyFilter<PersonConditionFilter>();
}


public CompanyMap ()
{
    Table("tblTable");
    Id(x => x.Id, "intId");
    Map(x => x.TypeId, "intTypeId");
    Map(x => x.Name, "strCompanyName");
    ApplyFilter<CompanyConditionFilter>();
}

最后,不要忘记在会话级别启用过滤器:

session.EnableFilter("CompanyCondition");
session.EnableFilter("PersonCondition");

var persons = session.QueryOver<Person>().List();
var companies = session.QueryOver<Company>().List();