1

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

大家好,我正在尝试使用自动映射为 Fluent NHibernate 组合一个(非常)简单的参考项目,特别是设置每个层次结构的表继承。我已经尝试从现有(工作)项目中复制配置,并且我已经浏览了 Fluent Wiki 页面上关于 AutoMapping 和继承的示例,并且都给了我相同的结果;我用每层级表设置的基类被视为普通类。

域模型如下所示:

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](名称,腿)值(?,?); 选择 SCOPE_IDENTITY()] ----> System.Data.SqlClient.SqlException:无效的对象名称“猫”。

需要注意的几点:

  • 这 '?' 如果我使用 SQL Profiler 检查,则正在填写。
  • 当我在 IsDiscriminated(Type type) 方法中放置断点时,我可以看到它被两种预期类型(Cat & Budgie)调用并且每次都返回 true。但是,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();
}

世界一切都很好:)

(即有三个错误)

这里的说明有点令人困惑,因为它首先谈到使用 .IgnoreBase<> 所以 NHibernate 不会将基础本身视为实体,然后在使用抽象层超类型时提到使用 .Includebase<>。我都试过了,但没有 Firo 的回答就没有运气。

4

1 回答 1

0

你忘了动物

public override bool IsDiscriminated(Type type)
{
    return typeof(Animal).IsAssigneableFrom(type);
}
于 2012-11-13T20:49:57.253 回答