当基类在fluent nhibernate中是抽象的时,如何实现每个具体类的表?
我有下面的场景当基类在fluent nhibernate中是抽象的时,如何实现每个具体类的表?,nhibernate,fluent-nhibernate,abstract-class,automapping,table-per-class,Nhibernate,Fluent Nhibernate,Abstract Class,Automapping,Table Per Class,我有下面的场景 public abstract class BaseClass { public virtual int Id {get; set}; public virtual string Name {get; set;} } public class FirstSubClass : BaseClass { //properties and behaviour here } public class SecondSubClass : BaseClass { //pro
public abstract class BaseClass
{
public virtual int Id {get; set};
public virtual string Name {get; set;}
}
public class FirstSubClass : BaseClass
{
//properties and behaviour here
}
public class SecondSubClass : BaseClass
{
//properties of SecondSubclass Here
}
public class ProcessStep
{
public virtual IList<BaseClass> ContentElements {get; set;}
}
默认情况下,fluent将忽略作为基类的抽象基类。
但是在类ProcessStep中,有返回IList的属性ContentElements,我得到一个异常:-
NHibernate.MappingException:关联引用未映射的类:基类
如果我使用IncludeBase(typeof(BaseClass))包含基类,那么它可以正常工作,但它会为基类和派生类创建一个表,并且记录与FK-PK关系相链接(每个子类的表)。
我想要实现的是每个具体类的表。也就是说,每个派生类都有自己的表,其中基类中有派生类的所有属性+属性。
你知道如何实现吗 由于我还没有看到您的映射,让我提供我的映射。你可以这样做
public class BaseClassMap:ClassMap<BaseClass>
{
public BaseClassMap()
{
/*
* Identity generator can't be native because subclass objects should be unique
* So use HiLo or Guid or other generators which will generate unique id on the child tables
*/
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Name);
UseUnionSubclassForInheritanceMapping(); // This is important - uses union-subclass mappings for the derived classes
}
}
public class FirstSubClassMap : SubclassMap<FirstSubClass>
{
public FirstSubClassMap()
{
Table("FirstSubClassTable");
// Map properties for FirstSubClass
}
}
public class SecondSubClassMap : SubclassMap<SecondSubClass>
{
public SecondSubClassMap()
{
Table("SecondSubClassTable");
// Map properties for SecondSubClass
}
}
public类BaseClassMap:ClassMap
{
公共BaseClassMap()
{
/*
*标识生成器不能是本机的,因为子类对象应该是唯一的
*因此,请使用HiLo或Guid或其他生成器,这些生成器将在子表上生成唯一的id
*/
Id(x=>x.Id).GeneratedBy.Guid();
Map(x=>x.Name);
UseUnionSubclass ForInheritanceMapping();//这很重要-对派生类使用union子类映射
}
}
公共类FirstSubclass映射:Subclass映射
{
公共子类映射()
{
表(“第一个子类表”);
//FirstSubClass的映射属性
}
}
公共类SecondSubclass映射:Subclass映射
{
public SecondSubClassMap()
{
表(“第二子类表”);
//第二个子类的映射属性
}
}
用带有nhibernate自动映射的抽象基类实现“每个具体类的表”继承策略让我头疼。但我想,我终于找到了一个解决方案,并想与大家分享。我还认为,它没有添加到自动映射文档中,因为它可能被认为是一种“弱”数据库设计
首先,以下是我找到的有关此主题的一些资源:
- fluent nhibernate(!automapping)中继承策略的示例实现
- 使用fluent nhibernate和自动映射记录继承策略
- (无法添加其他链接)https://github。com/jagregory/fluent-nhibernate/pull/25/commissions/2984c8c4e89aa4cec8625538f763c5931121a4e7 Bug Fix Union子类实现(每个具体类的表)
//为已知的基本模型设置联合子类策略
model.Override(m=>m.UseUnionSubclass ForInheritanceMapping())
公共类AbstractRightEntryMappingOverride:IAutoMappingOverride
{
公共无效替代(自动映射)
{
mapping.UseUnionSubclassForInheritanceMapping();
}
}
//您需要告诉nhibernate哪里可以找到覆盖的映射。
//您只需再次添加程序集即可。
ModelAssembly.ForEach(a=>model=model.UseOverridesFromAssembly(a));
我使用的是自动映射,因此我没有单独映射类的规定。您可以将自动映射与自定义映射混合使用,这样您可以仅为特定类提供映射,其余类可以使用自动映射进行映射。类似这样的流畅.Configure(configuration).Mappings(cfg=>{cfg.AutoMappings.Add(..);cfg..FluentMappings.AddFromAssembly(您的自定义映射程序集);})
public class BaseClassMap:ClassMap<BaseClass>
{
public BaseClassMap()
{
/*
* Identity generator can't be native because subclass objects should be unique
* So use HiLo or Guid or other generators which will generate unique id on the child tables
*/
Id(x => x.Id).GeneratedBy.Guid();
Map(x => x.Name);
UseUnionSubclassForInheritanceMapping(); // This is important - uses union-subclass mappings for the derived classes
}
}
public class FirstSubClassMap : SubclassMap<FirstSubClass>
{
public FirstSubClassMap()
{
Table("FirstSubClassTable");
// Map properties for FirstSubClass
}
}
public class SecondSubClassMap : SubclassMap<SecondSubClass>
{
public SecondSubClassMap()
{
Table("SecondSubClassTable");
// Map properties for SecondSubClass
}
}
// abstractBaseTypes is just a simple enumeration of base types
// model is the AutoPersistenceModel
abstractBaseTypes.ForEach(m => model = model.IncludeBase(m));
//sets the union subclass strategy for the known base model
model.Override<SuperType>(m => m.UseUnionSubclassForInheritanceMapping()))
public class AbstractRightEntryMappingOverride : IAutoMappingOverride<AbstractRightEntry>
{
public void Override(AutoMapping<AbstractRightEntry> mapping)
{
mapping.UseUnionSubclassForInheritanceMapping();
}
}
// You need to tell nhibernate where to find the overriden mappings.
// You simply can add the assemblies again.
modelAssemblies.ForEach(a => model = model.UseOverridesFromAssembly(a));