【问题标题】:how to achieve table per concrete class when base class is abstract in fluent nhibernate?当基类在流利的nhibernate中是抽象的时,如何实现每个具体类的表?
【发布时间】:2011-09-12 08:44:25
【问题描述】:

我有以下场景

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

对于映射,我使用了以下代码 sn-p :-

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 和派生类创建一个表,并且记录与 FK-PK 关系链接(每个子类的表)。 我想要实现的是每个具体类的表。也就是说,每个派生类都有自己的表,其中将有派生类的所有属性+基类中的属性。 知道如何实现吗?

【问题讨论】:

    标签: nhibernate fluent-nhibernate abstract-class automapping table-per-class


    【解决方案1】:

    由于我没有看到您的地图,所以让我提供我的。您可以通过这样做来实现这一目标

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

    【讨论】:

    • 我正在使用自动映射,所以我没有规定单独映射类。
    • 您可以将自动映射与自定义映射混合使用,这样您就可以只为特定的类提供映射,其余的类可以使用自动映射进行映射。像这样 Fluently.Configure(configuration).Mappings(cfg => { cfg.AutoMappings.Add(....); cfg..FluentMappings.AddFromAssembly(Your custom mapping assembly);})
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 1970-01-01
      • 2011-08-03
      • 1970-01-01
      相关资源
      最近更新 更多