C# Fluent NHibernate-添加鉴别器时遇到的问题

C# Fluent NHibernate-添加鉴别器时遇到的问题,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我有一个类,文档和几个子类(发票,采购订单,等等)。我在文档中添加了一个鉴别器,如下所示: public class DocumentMapOverride : IAutoMappingOverride<Document> { public void Override(AutoMapping<Document> mapping) { mapping.DiscriminateSubClassesOnColumn("DocumentType")

我有一个类,
文档
和几个子类(
发票
采购订单
,等等)。我在
文档中添加了一个鉴别器,如下所示:

public class DocumentMapOverride : IAutoMappingOverride<Document>
{
    public void Override(AutoMapping<Document> mapping)
    {
        mapping.DiscriminateSubClassesOnColumn("DocumentType");
    }
}
有什么建议吗

  • FluentNHibernate 1.0
  • SQLite
  • C#/.Net4.0

这可能完全不相关,但当我尝试与此类似的映射时,我发现Nhibernate试图将“reallyVeryInCreditableLongNamespace.Invoice”插入到discriminator列中,而不仅仅是类型名称。因为我的专栏无法容纳所有这些字符,所以失败了


我可以看出您的错误消息似乎与此不符,但有时错误会产生误导,因此我认为值得一试。

我无法重现此问题。我已下载的最新版本,以下程序运行良好:

using System;
using System.Reflection;
using FluentNHibernate;
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
using NHibernate;
using NHibernate.Tool.hbm2ddl;

public interface IEntity
{
    int Id { get; set; }
}

public abstract class MyBaseClass : IEntity
{
    public virtual int Id { get; set; }

    public class MyBaseClassMap : IAutoMappingOverride<MyBaseClass>
    {
        public void Override(AutoMapping<MyBaseClass> mapping)
        {
            mapping.DiscriminateSubClassesOnColumn("ChildClassType", "MyBaseClassMap");
        }
    }
}

public class MyFirstChildClass : MyBaseClass
{
    public virtual string Child1 { get; set; }
}

public class MySecondChildClass : MyBaseClass
{
    public virtual string Child2 { get; set; }
}

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        string table = string.Format("{0}_HiLo", instance.EntityType.Name);
        instance.GeneratedBy.HiLo(table, "next_hi", "100");
    }
}

public class MyMappingConfig : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        if (type.GetInterface(typeof(IEntity).FullName) != null)
            return true;

        return false;
    }

    public override bool AbstractClassIsLayerSupertype(Type type)
    {
        if (type == typeof(IEntity))
            return true;
        return false;
    }

    public override bool IsId(Member member)
    {
        return member.Name == "Id";
    }

    public override bool IsDiscriminated(Type type)
    {
        if (type.IsAssignableFrom(typeof(MyBaseClass)) || type.IsSubclassOf(typeof(MyBaseClass)))
            return true;

        return false;
    }
}


public class Program
{
    private static ISession InitializeNHibertnat(Assembly mapAssembly)
    {
        var automappingConfiguration = new MyMappingConfig();

        var fluentConfiguration =
            Fluently.Configure().Database(SQLiteConfiguration.Standard.InMemory());

        fluentConfiguration = fluentConfiguration
            .Mappings(m => m.AutoMappings
                               .Add(AutoMap.Assembly(mapAssembly, automappingConfiguration)
                                        .Conventions.Add<PrimaryKeyConvention>()
                                        .UseOverridesFromAssembly(mapAssembly)))
            .Mappings(m => m.FluentMappings
                               .AddFromAssembly(mapAssembly))
            .Mappings(m => m.HbmMappings
                               .AddFromAssembly(mapAssembly))
            .ExposeConfiguration(cfg => cfg.SetProperty("generate_statistics", "true"))
            .ExposeConfiguration(cfg => cfg.SetProperty("show_sql", "true"))
            .ExposeConfiguration(cfg => cfg.SetProperty("adonet.batch_size", "1"));


        var configuration = fluentConfiguration.BuildConfiguration();
        var sessionFactory = configuration.BuildSessionFactory();
        var session = sessionFactory.OpenSession();
        new SchemaExport(configuration).Execute(false, true, false, session.Connection, null);

        return session;
    }

    static void Main()
    {
        var mfcc = new MyFirstChildClass();
        mfcc.Id = 1;
        mfcc.Child1 = "Child One";

        var mscc = new MySecondChildClass();
        mscc.Id = 2;
        mscc.Child2 = "Child Two";

        var Session = InitializeNHibertnat(Assembly.GetExecutingAssembly());
        using (var tx = Session.BeginTransaction())
        {
            Session.Save(mfcc);
            Session.Save(mscc);
            tx.Commit();
        }
    }
}

在我的测试中,我还为此控制台应用程序使用了
System.Data.SQLite、Version=1.0.65.0、Culture=neutral、PublicKeyToken=db937bc2d44ff139
和targeted.NET 4.0。在Windows 7 x64上运行。

此NUnit测试显示我的错误。谢谢-我将尝试今天或明天升级到Fluent 1.1。
using System;
using System.Reflection;
using FluentNHibernate;
using FluentNHibernate.Automapping;
using FluentNHibernate.Automapping.Alterations;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using FluentNHibernate.Conventions;
using FluentNHibernate.Conventions.Instances;
using NHibernate;
using NHibernate.Tool.hbm2ddl;

public interface IEntity
{
    int Id { get; set; }
}

public abstract class MyBaseClass : IEntity
{
    public virtual int Id { get; set; }

    public class MyBaseClassMap : IAutoMappingOverride<MyBaseClass>
    {
        public void Override(AutoMapping<MyBaseClass> mapping)
        {
            mapping.DiscriminateSubClassesOnColumn("ChildClassType", "MyBaseClassMap");
        }
    }
}

public class MyFirstChildClass : MyBaseClass
{
    public virtual string Child1 { get; set; }
}

public class MySecondChildClass : MyBaseClass
{
    public virtual string Child2 { get; set; }
}

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        string table = string.Format("{0}_HiLo", instance.EntityType.Name);
        instance.GeneratedBy.HiLo(table, "next_hi", "100");
    }
}

public class MyMappingConfig : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        if (type.GetInterface(typeof(IEntity).FullName) != null)
            return true;

        return false;
    }

    public override bool AbstractClassIsLayerSupertype(Type type)
    {
        if (type == typeof(IEntity))
            return true;
        return false;
    }

    public override bool IsId(Member member)
    {
        return member.Name == "Id";
    }

    public override bool IsDiscriminated(Type type)
    {
        if (type.IsAssignableFrom(typeof(MyBaseClass)) || type.IsSubclassOf(typeof(MyBaseClass)))
            return true;

        return false;
    }
}


public class Program
{
    private static ISession InitializeNHibertnat(Assembly mapAssembly)
    {
        var automappingConfiguration = new MyMappingConfig();

        var fluentConfiguration =
            Fluently.Configure().Database(SQLiteConfiguration.Standard.InMemory());

        fluentConfiguration = fluentConfiguration
            .Mappings(m => m.AutoMappings
                               .Add(AutoMap.Assembly(mapAssembly, automappingConfiguration)
                                        .Conventions.Add<PrimaryKeyConvention>()
                                        .UseOverridesFromAssembly(mapAssembly)))
            .Mappings(m => m.FluentMappings
                               .AddFromAssembly(mapAssembly))
            .Mappings(m => m.HbmMappings
                               .AddFromAssembly(mapAssembly))
            .ExposeConfiguration(cfg => cfg.SetProperty("generate_statistics", "true"))
            .ExposeConfiguration(cfg => cfg.SetProperty("show_sql", "true"))
            .ExposeConfiguration(cfg => cfg.SetProperty("adonet.batch_size", "1"));


        var configuration = fluentConfiguration.BuildConfiguration();
        var sessionFactory = configuration.BuildSessionFactory();
        var session = sessionFactory.OpenSession();
        new SchemaExport(configuration).Execute(false, true, false, session.Connection, null);

        return session;
    }

    static void Main()
    {
        var mfcc = new MyFirstChildClass();
        mfcc.Id = 1;
        mfcc.Child1 = "Child One";

        var mscc = new MySecondChildClass();
        mscc.Id = 2;
        mscc.Child2 = "Child Two";

        var Session = InitializeNHibertnat(Assembly.GetExecutingAssembly());
        using (var tx = Session.BeginTransaction())
        {
            Session.Save(mfcc);
            Session.Save(mscc);
            tx.Commit();
        }
    }
}
NHibernate: select next_hi from MyBaseClass_HiLo
NHibernate: update MyBaseClass_HiLo set next_hi = @p0 where next_hi = @p1;@p0 = 2, @p1 = 1
NHibernate: INSERT INTO "MyBaseClass" (Child1, ChildClassType, Id) VALUES (@p0, 'MyFirstChildClass', @p1);@p0 = 'Child One', @p1 = 101
NHibernate: INSERT INTO "MyBaseClass" (Child2, ChildClassType, Id) VALUES (@p0, 'MySecondChildClass', @p1);@p0 = 'Child Two', @p1 = 102