Table-每个子类的流畅 nhibernate 不工作
Table-per-subclass fluent nhibernate not working
我定义了以下 classes:
我的数据库中有这些 table:
我流畅的 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 应该足够聪明,可以在我查询特定的 subclass 时确定要实例化的 subclass。但是,当我执行以下语句时:
var result = Session.QueryOver<BusinessUnit>()
.Where(x => x.Code == "Acme")
.SingleOrDefault();
抛出异常,因为它无法创建抽象 BusinessUnit class 的实例。我能让它工作的唯一方法是将 Company 指定为 QueryOver 的类型参数。
我已经确认使用鉴别器会中断,因为 NHibernate 正在寻找存在于单个 table 中的所有列。但是,如果没有它,我很难看到 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 语句?我错过了什么?
您的数据似乎不一致。将鉴别器映射与可选的一起使用可能会更好。如果您真的不需要代码中的 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);
});
}
}
我定义了以下 classes:
我的数据库中有这些 table:
我流畅的 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 应该足够聪明,可以在我查询特定的 subclass 时确定要实例化的 subclass。但是,当我执行以下语句时:
var result = Session.QueryOver<BusinessUnit>()
.Where(x => x.Code == "Acme")
.SingleOrDefault();
抛出异常,因为它无法创建抽象 BusinessUnit class 的实例。我能让它工作的唯一方法是将 Company 指定为 QueryOver 的类型参数。
我已经确认使用鉴别器会中断,因为 NHibernate 正在寻找存在于单个 table 中的所有列。但是,如果没有它,我很难看到 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 语句?我错过了什么?
您的数据似乎不一致。将鉴别器映射与可选的一起使用可能会更好。如果您真的不需要代码中的 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);
});
}
}