【发布时间】:2015-09-13 16:48:43
【问题描述】:
我定义了以下类:
还有我数据库中的这些表:
我流畅的 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);
}
}
问题 #1 据我所知,我的代码和数据库的设置与我能找到的每个示例相同。根据这些文章,NHibernate 应该足够聪明,可以在我查询特定子类时确定要实例化哪个子类。但是,当我执行以下语句时:
var result = Session.QueryOver<BusinessUnit>()
.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;
}
我得到一个异常,表明 UPDATE 语句与外键约束冲突。更新声明!!!!显然有些事情仍然不对劲。 QueryOver 调用如何导致 UPDATE 语句?我错过了什么?
【问题讨论】:
-
NHibernate 使用其中一个子表中的存在性作为要实例化哪个类的指示符。看起来有一个 acme 条目在其他表之一中没有相应的条目
-
不知道你是怎么得到的。 “Acme”存在于 BusinessUnits 和 CompanyData 表中。
-
我重现了您描述的错误,其中基表中的条目和子表中的条目丢失。也许还有其他情况会出现相同的错误
-
检查更新语句以查看错误可能来自何处。也许您没有发布错误来源的类
-
在改用@filo 的方法并向后工作后,我终于弄清楚了我最初的实现出了什么问题。 ParentId 属性是一个 Guid,但其中一条记录在数据库中为空。 NHibernate 不是因为 Guid 值(不是)而抛出异常,而是认为属性是脏的并尝试更新记录!只有通过对日志的深入分析,我才发现表明它认为 ParentId 是脏的语句。我碰巧是因为 null 值而使属性 Guid?而且,瞧!一切正常。
标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping queryover