10

我有以下情况

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;}  
}

对于映射,我使用了以下代码片段:-

this._sessionFactory =
                          Fluently.Configure().Database(SQLiteConfiguration.Standard
                          .ConnectionString(@"Data Source=SqliteTestSqlDataAccess.s3db;    Version=3; New=True; Pooling=True; Max Pool Size=1;"))
                          .Mappings(m => m.AutoMappings.Add(AutoMap.Assembly(assemblyWithDomainClasses).Conventions.Add(DefaultCascade.All())))
                          .ExposeConfiguration(BuildSchema)
                          .BuildSessionFactory();

默认情况下,fluent 将忽略抽象基类 BaseClass。但是在ProcessStep类中有返回IList的属性 ContentElements ,我得到一个异常:- NHibernate.MappingException :关联引用未映射的类:BaseClass

如果我使用 IncludeBase(typeof(BaseClass)) 包含基类,那么它可以正常工作,但它会为 BaseClass 和 Derived 类创建一个表,并且记录与 FK-PK 关系链接(每个子类的表)。我想要实现的是每个具体类的表。也就是说,每个派生类都有自己的表,其中将有派生类的所有属性+基类中的属性。知道如何实现吗?

4

2 回答 2

9

由于我还没有看到你的映射,让我提供我的。你可以通过这样做来实现这一点

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
    }
}
于 2011-09-29T06:41:34.167 回答
2

使用带有休眠自动映射的抽象基类来实现“每个具体类的表”继承策略让我很头疼。但我想,我终于找到了解决办法,想和大家分享一下。我还认为,它没有添加到自动映射文档中,因为它可能被认为是“弱”的数据库设计。

首先是我找到的关于这个主题的一些资源:

这些资源基本上描述了您需要如何做:

  1. 正如您已经提到的,流利的 nhibernate 忽略了抽象基类。所以你需要明确地添加它们。
// abstractBaseTypes is just a simple enumeration of base types
// model is the AutoPersistenceModel
abstractBaseTypes.ForEach(m => model = model.IncludeBase(m));
  1. a)如果您在编译时知道抽象基类型,则可以使用
//sets the union subclass strategy for the known base model
model.Override<SuperType>(m => m.UseUnionSubclassForInheritanceMapping()))
  1. b) 如果您不知道具体类型,您可以为每个基本类型创建映射覆盖:
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));
于 2017-10-17T15:39:15.750 回答