每个子类的表fluent nhibernate不工作

每个子类的表fluent nhibernate不工作,nhibernate,fluent-nhibernate,fluent-nhibernate-mapping,queryover,Nhibernate,Fluent Nhibernate,Fluent Nhibernate Mapping,Queryover,我定义了以下类: 我数据库中的这些表: 我的fluent NHibernate映射是: public class BusinessUnitMap : ClassMap<BusinessUnit> { public BusinessUnitMap() { Table("BusinessUnits"); Id(x => x.Id); Map(x => x.Code); Map(x =>

我定义了以下类:

我数据库中的这些表:

我的fluent NHibernate映射是:

public class BusinessUnitMap : ClassMap<BusinessUnit>
{
    public BusinessUnitMap()
    {
        Table("BusinessUnits");

        Id(x => x.Id);

        Map(x => x.Code);
        Map(x => x.Name);
        Map(x => x.ParentId);
        Map(x => x.Type).Column("Type").CustomType<BusinessUnitType>();
    }
}

public class CompanyMap : SubclassMap<Company>
{
    public CompanyMap()
    {
        Table("CompanyData");

        KeyColumn("BusinessUnitID");

        Map(x => x.Something);
    }
}

public class FranchiseeMap : SubclassMap<Franchisee>
{
    public FranchiseeMap()
    {
        Table("FranchiseeData");

        KeyColumn("BusinessUnitID");

        Map(x => x.SomethingDifferent);
    }
}

public class StoreMap : SubclassMap<Store>
{
    public StoreMap()
    {
        Table("StoreData");

        KeyColumn("BusinessUnitID");

        Map(x => x.SomethingElse);
    }
}
public类BusinessUnitMap:ClassMap
{
public BusinessUnitMap()
{
表(“业务单位”);
Id(x=>x.Id);
Map(x=>x.Code);
Map(x=>x.Name);
Map(x=>x.ParentId);
Map(x=>x.Type).Column(“Type”).CustomType();
}
}
公共类CompanyMap:子类映射
{
上市公司地图()
{
表(“公司数据”);
KeyColumn(“BusinessUnitID”);
Map(x=>x.Something);
}
}
公共类映射:子类映射
{
公共特许经营地图()
{
表(“特许经营数据”);
KeyColumn(“BusinessUnitID”);
Map(x=>x.somethingthesis);
}
}
公共类存储映射:子类映射
{
公共存储地图()
{
表(“存储数据”);
KeyColumn(“BusinessUnitID”);
Map(x=>x.SomethingElse);
}
}
问题1 据我所知,我的代码和数据库的设置与我能找到的每个示例都一样。根据这些文章,当我查询特定的子类时,NHibernate应该足够聪明来确定实例化哪个子类。但是,当我执行以下语句时:

var result = Session.QueryOver<BusinessUnit>()
                    .Where(x => x.Code == "Acme")
                    .SingleOrDefault();
var result=Session.QueryOver()
.Where(x=>x.Code==“Acme”)
.SingleOrDefault();
引发异常,因为它无法创建抽象BusinessUnit类的实例。我能让它工作的唯一方法是指定Company作为QueryOver的类型参数

我已经确认,使用鉴别器会中断,因为NHibernate正在查找单个表中存在的所有列。但是,如果没有它,我很难理解NHibernate如何知道实例化什么类型

我做错了什么?我的映射中的问题,我查询的方式

问题2 当我将查询更改为以下内容时:

public T WithCode<T>(String code)
    where T : BusinessUnit
{
    var result = Session.QueryOver<T>()
                        .Where(x => x.Code == code)
                        .SingleOrDefault();

    return result;
}
publictwithcode(字符串代码)
其中T:业务单位
{
var result=Session.QueryOver()
.Where(x=>x.Code==Code)
.SingleOrDefault();
返回结果;
}

我得到一个异常,表明UPDATE语句与外键约束冲突。更新声明!!!!显然,有些事情仍然不对。QueryOver调用如何生成UPDATE语句?我遗漏了什么?

看起来您的数据不一致。最好将discrimnator映射与可选项一起使用。如果代码中确实不需要BusinessUnitType属性,那么只需删除该属性周围的所有内容
Type

public enum BusinessUnitType
{
    Company,
    Franchisee
}

public abstract class BusinessUnit
{
    public virtual int Id { get; set; }
    public virtual string Code { get; set; }
    public virtual string Name { get; set; }
    public virtual BusinessUnit Parent { get; set; }
    public abstract BusinessUnitType Type { get; }
}

public class Company : BusinessUnit
{
    public virtual string Something { get; set; }

    public override BusinessUnitType Type { get { return BusinessUnitType.Company; } }
}

public class Franchisee : BusinessUnit
{
    public virtual string SomethingDifferent { get; set; }

    public override BusinessUnitType Type { get { return BusinessUnitType.Franchisee; } }
}

public class BusinessUnitMap : ClassMap<BusinessUnit>
{
    public BusinessUnitMap()
    {
        Table("BusinessUnits");

        Id(x => x.Id);

        Map(x => x.Code);
        Map(x => x.Name);
        References(x => x.Parent);

        DiscriminateSubClassesOnColumn("Type");

        Map(x => x.Type, "Type")
            .Access.None()
            .CustomType<BusinessUnitType>().ReadOnly();
    }
}

public class CompanyMap : SubclassMap<StrangeTablePerSubclass.Company>
{
    public CompanyMap()
    {
        DiscriminatorValue((int)new Company().Type);

        Join("CompanyData", join =>
        {
            join.KeyColumn("BusinessUnitID");
            join.Optional();
            join.Map(x => x.Something);
        });
    }
}

public class FranchiseeMap : SubclassMap<Franchisee>
{
    public FranchiseeMap()
    {
        DiscriminatorValue((int)new Franchisee().Type);
        Join("FranchiseeData", join =>
        {
            join.KeyColumn("BusinessUnitID");
            join.Optional();
            join.Map(x => x.SomethingDifferent);
        });
    }
}
public enum BusinessUnitType
{
公司,
特许经营人
}
公共抽象类业务单元
{
公共虚拟整数Id{get;set;}
公共虚拟字符串代码{get;set;}
公共虚拟字符串名称{get;set;}
公共虚拟业务单元父级{get;set;}
公共抽象BusinessUnitType类型{get;}
}
公共类公司:业务单位
{
公共虚拟字符串Something{get;set;}
公共重写BusinessUnitType类型{get{return BusinessUnitType.Company;}}
}
公共类特许经营人:业务单位
{
公共虚拟字符串SomethingDifferent{get;set;}
公共重写BusinessUnitType类型{get{return BusinessUnitType.特许经营人;}
}
公共类BusinessUnitMap:ClassMap
{
public BusinessUnitMap()
{
表(“业务单位”);
Id(x=>x.Id);
Map(x=>x.Code);
Map(x=>x.Name);
参考文献(x=>x.Parent);
区分子类子列(“类型”);
映射(x=>x.Type,“Type”)
.Access.None()
.CustomType().ReadOnly();
}
}
公共类CompanyMap:子类映射
{
上市公司地图()
{
鉴别器值((int)新公司().Type);
加入(“公司数据”,加入=>
{
join.KeyColumn(“BusinessUnitID”);
join.Optional();
join.Map(x=>x.Something);
});
}
}
公共类映射:子类映射
{
公共特许经营地图()
{
鉴别器值((int)新特许经营人().Type);
加入(“特许经营”,加入=>
{
join.KeyColumn(“BusinessUnitID”);
join.Optional();
join.Map(x=>x.somethingthesis);
});
}
}

NHibernate使用其中一个子表中的existance作为要实例化的类的指示器。看起来有一个acme条目在另一个表中没有对应的条目,但不确定您是如何得到它的。“Acme”在BusinessUnits和CompanyData表中都存在。我复制了您描述的错误,其中基本表中有一个条目,子表中缺少一个条目。可能还有其他显示相同错误的场景检查update语句以查看错误可能来自何处。也许你没有发布导致错误的类。在改变@filo的方法并向后工作之后,我终于发现了我最初的实现出了什么问题。ParentId属性是Guid,但其中一条记录在数据库中为null。NHibernate不会因为null Guid值(not)而引发异常,而是认为该属性不干净并尝试更新记录!只有通过对日志的深入分析,我才发现这条语句表明它认为ParentId是肮脏的。我冒了一个险,这是因为空值,并使属性Guid?还有,瞧!一切正常。鉴别器要求所有数据都在一个表中。虽然这个示例很简单,但它只是一个示例,我去掉了每个子类实际拥有的大量属性。当鉴别器包含一个表中的所有内容时,连接元素从其他元素获取属性