NHibernate映射:将层次结构保存到单个表而不带鉴别器

时间:2010-12-17 13:09:43

标签: c# .net nhibernate orm

我有一个非常可扩展的模块化应用程序。我想从其他程序集扩展映射的Entites。然而,我仍然需要对基类进行操作。

示例:

程序集A中的父类映射:

    public class PersonMap : ClassMap<Person> 
    {
        public PersonMap()
        {
            Table("Persons");

            Id(x => x.Id).GeneratedBy.Assigned();
        }
}

程序集B中的子类映射:

public class EmployeeMap : SubclassMap<Employee>
{
    public EmployeeMap()
    {
        Table("Persons");
        Extends(typeof(Person));

        KeyColumn("Id");

        LazyLoad();

        HasMany<Assignments>(x => x.Assignments).KeyColumn("Id").Inverse().Cascade.AllDeleteOrphan().LazyLoad().NotFound.Ignore();
    }
}

现在每当我在Assembly A的某些代码中创建Person时,它就会被NHibernate保存为Employee。每当我保存一个Person并尝试在程序集A中刷新它时,由于代理会导致类转换异常。程序集A必须不依赖于程序集B.

我需要在程序集A的所有方法中对父类进行操作。子类仅用于其他程序集。

我该如何映射这样的东西?我如何告诉NHibernate将它保存为父类?我使用SaveOrUpdate来持久保存实体;如何正确扩展实体,然后将它们保存到同一个表中而没有鉴别器? NHibernate不能按对象类型区分吗?有解决方法吗?

我不想指定手动代理,因为我必须为每个实体创建代理!由于依赖性问题,我无法使用访问者模式。

我需要一种方法来扩展不同程序集中的映射实体而不会出现这样的问题!数据库是遗留的,我无法改变它。你会如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

将层次结构映射到单个表而没有鉴别器的目标是一个难题。数据层中必须有SOMETHING,它为DAL提供了一条特定记录是员工而不仅仅是人员的线索。由于您没有在员工的Persons表上映射任何其他字段,并且没有提供鉴别器,因此没有任何关于Persons表的单个记录可以区分人员和派生更多的员工。

您能否提供用于检索个人记录的代码?根据我的经验,NHibernate查询几乎总是需要域类型来保持水合。在这种情况下,NHibernate可能会尝试创建它知道的派生类型最多的对象,并且由于它无法区分基本Person和派生的Employee之间的区别,因此所有人员都是Employees。您可以尝试Linq,它强制强类型对象水合,而不是HQL或其他不太强烈引用的查询。

答案 1 :(得分:0)

通过在同一个表上使用HasOne Mapping并且不使用子类来解决它。这不会产生理想的代码,但是没有问题。