流畅的NHibernate Automapping - 每个表的继承不写入鉴别器列

时间:2012-11-12 03:58:49

标签: fluent-nhibernate fluent-nhibernate-mapping

使用   NHibernate:3.3.2   流利的NHibernate:1.3.0   .NET 4.0

大家好,我正在尝试使用自动化为Fluent NHibernate组建一个(非常)简单的参考项目,特别是设置每层次的表继承。我已经尝试从现有(工作)项目中复制配置,并且我已经在Fluent Wiki页面上运行了关于AutoMapping和继承的示例,并且两者都给出了相同的结果;我使用table-per-hirearchy设置的基类被视为常规类。

域模型如下所示:

namespace Tests
{
    public abstract class Animal
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual int Legs { get; set; }
    }

    public class Cat : Animal {}

    public class Budgie : Animal {}
}
像我说的那样简单,只是为了说明继承。我知道'基础'应该在基类上被覆盖:)

AutoMapping配置如下所示:

public class AutoMappingConfig : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        var include = type.IsSubclassOf(typeof(Animal));
        Debug.WriteLineIf(include, string.Format("Included {0} in NHibernate mapping.", type));
        return include;
    }

    public override bool IsDiscriminated(Type type)
    {
        var result = type.In(
            (typeof(Cat)),
            (typeof(Budgie))
            );

        return result;
    }
}

最后,配置/会话创建如下:

public static ISession NewSession()
{
    var cfg = new AutoMappingConfig();

    var map = AutoMap.AssemblyOf<Animal>(cfg)
        .IgnoreBase<Animal>();

    var dbConfiguration = MsSqlConfiguration.MsSql2008
        .ConnectionString(ConfigurationManager.ConnectionStrings["testdb"].ConnectionString);

    return Fluently.Configure()
        .Mappings(m =>m.AutoMappings.Add(map))
        .Database(dbConfiguration)
        .BuildSessionFactory()
        .OpenSession();
}

将它们放在一起,我尝试创建几个新记录:

[Test]
public void CreateData()
{
    var tiddles = new Cat {Name = "Tiddles", Legs = 4};
    var kylie = new Budgie {Name = "Kylie", Legs = 2};

    using (var transaction = _session.BeginTransaction())
    {
        _session.Save(tiddles); // exception!
        _session.Save(kylie);

        transaction.Commit();
        }
    }
}

错误是:

  

NHibernate.Exceptions.GenericADOException:无法插入:   [Tests.Cat] [SQL:INSERT INTO [Cat](Name,Legs)VALUES(?,?);选择   SCOPE_IDENTITY()] ----&gt; System.Data.SqlClient.SqlException:无效   对象名称'Cat'。

有几点需要注意:

  • '?'如果我查看SQL Profiler,我们正在填写。
  • 当我在IsDiscriminated(类型类型)方法中放置断点时,我可以看到 它被称为两种预期类型(Cat&amp; Budgie)并且每次都返回真实状态。但是,SQL正在写入错误的表,而不是写入鉴别器列。即使有人告诉他们这些课程受到歧视,但他们并没有受到这样的待遇。
  • 在表格中,Id列是一个自动增量标识列。
  • 我尝试将其他属性添加到两个子类中,以防它们需要的不仅仅是基本属性来触发正确的行为(没有区别)。

非常感谢任何帮助。我现在确信它显而易见,但是这里没有人知道NHibernate(LightSpeed是另一回事),所以我不知道是什么。


好的,所以最终的工作代码如下所示:

public class AutoMappingConfig : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        var include = type.IsSubclassOf(typeof(Animal)) || type == typeof (Animal);
        Debug.WriteLineIf(include, string.Format("Included {0} in NHibernate mapping.", type));
        return include;
    }

    public override bool IsDiscriminated(Type type)
    {
        return typeof(Animal).IsAssignableFrom(type);
    }
}

public static ISession NewSession()
{
    var cfg = new AutoMappingConfig();

    var map = AutoMap.AssemblyOf<Animal>(cfg)
        .IncludeBase<Animal>();

    var dbConfiguration = MsSqlConfiguration.MsSql2008
        .ConnectionString(ConfigurationManager.ConnectionStrings["testdb"].ConnectionString);

    return Fluently.Configure()
        .Mappings(m =>m.AutoMappings.Add(map))
        .Database(dbConfiguration)
        .BuildSessionFactory()
        .OpenSession();
}

一切顺利于世界:)

(即有三个错误)

指令here有点令人困惑,因为它首先谈到使用.IgnoreBase&lt;&gt;因此NHibernate本身不会将基础视为实体,后来提到使用.Includebase&lt;&gt;当使用抽象层超类型时。我试过了两个,但没有Firo的回答没有运气。

1 个答案:

答案 0 :(得分:0)

你忘记了动物

public override bool IsDiscriminated(Type type)
{
    return typeof(Animal).IsAssigneableFrom(type);
}