Nhibernate 复合密钥与继承

Nhibernate 复合密钥与继承,nhibernate,fluent-nhibernate,nhibernate-mapping,fluent-nhibernate-mapping,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Fluent Nhibernate Mapping,我有以下类和映射 abstract class BaseClass { public virtual int Keypart1 { get; set; } public virtual int Keypart2 { get; set; } // overridden Equals() and GetHashCode() } class InheritingClass : BaseClass { } class BaseClassMap : ClassMap<B

我有以下类和映射

abstract class BaseClass
{
    public virtual int Keypart1 { get; set; }
    public virtual int Keypart2 { get; set; }

    // overridden Equals() and GetHashCode()
}

class InheritingClass : BaseClass
{
}

class BaseClassMap : ClassMap<BaseClass>
{
    public BaseClassMap()
    {
        CompositeId()
            .KeyProperty(x => x.Keypart1)
            .KeyProperty(x => x.Keypart2);
    }
}

class InheritingClassMap : SubclassMap<InheritingClass>
{
    public InheritingClassMap()
    {
        KeyColumn("Keypart1");
        KeyColumn("Keypart2");
    }
}
NH似乎试图将抽象基类实例化为compositekey,但失败了。我能解决这个问题吗

更新:我的测试代码

var config = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
    .Mappings(m => m.FluentMappings
        .Add<BaseClassMap>()
        .Add<InheritingClassMap>()
    )
    .BuildConfiguration();

var sf = config.BuildSessionFactory();

using (var session = sf.OpenSession())
{
    new SchemaExport(config).Execute(false, true, false, session.Connection, null);

    var obj = new InheritingClass
    {
        Keypart1 = 1,
        Keypart2 = 2,
    };

    session.Save(obj);
    session.Flush();
    session.Clear();

    // throws here
    var result = session.CreateCriteria<InheritingClass>().List<InheritingClass>();
}
var config=fluntly.Configure()
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
.Mappings(m=>m.FluentMappings
.Add()
.Add()
)
.BuildConfiguration();
var sf=config.BuildSessionFactory();
使用(var session=sf.OpenSession())
{
新SchemaExport(config.Execute)(false、true、false、session.Connection、null);
var obj=新的继承类
{
键部件1=1,
键部件2=2,
};
session.Save(obj);
session.Flush();
session.Clear();
//扔到这里
var result=session.CreateCriteria().List();
}

您的数据库是什么样子的?根据映射,每个子类映射使用一个表。在这种情况下,如果在
InheritingClass
的表中找不到行,NHibernate将尝试创建
BaseClass
的实例

编辑:NHibernate映射中的
有一个
abstract=“true”
属性,它可能会解决您的问题。但是在Fluent NHibernate中,对于
类映射
,这似乎并没有公开,只针对
子类映射
(这对您没有帮助)


但是,您也可以通过使用复合ID的组件来解决这个问题(这样NHibernate就不需要为其EntityKey创建
基类
对象。有关这方面的信息,请参阅。

thx to cremor这就是我最终得到的结果

abstract class BaseClass
{
    public virtual BaseClassId Key { get; set; }
}

class BaseClassId
{
    public virtual int Keypart1 { get; set; }
    public virtual int Keypart2 { get; set; }

    public override bool Equals(object obj)
    {
        var other = obj as BaseClassId;
        return (other != null) && (Keypart1 == other.Keypart1) && (Keypart2 == other.Keypart2);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return Keypart1 + Keypart2;
        }
    }
}

// mapping
CompositeId(b => b.Key)
    .KeyProperty(x => x.Keypart1)
    .KeyProperty(x => x.Keypart2);


var obj = new InheritingClass
{
    Key = new BaseClassId
    {
        Keypart1 = 1,
        Keypart2 = 2,
    }
};

NH创建它似乎是为了将密钥存储在EntityKeysetting
config.GetClassMapping(typeof(BaseClass))中.IsAbstract=true;
没有帮助。我会调查entitykey@Firo我想我也遇到了同样的问题。我需要恢复使用hbm.xml文件吗?这个
GetHashCode
实现会有问题。如果两个对象比较相等,每个对象的GetHashCode方法必须返回相同的值。@cremor right,impElementation仅用于最小的示例。实际实体使用keyparts实现它
var config = Fluently.Configure()
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql())
    .Mappings(m => m.FluentMappings
        .Add<BaseClassMap>()
        .Add<InheritingClassMap>()
    )
    .BuildConfiguration();

var sf = config.BuildSessionFactory();

using (var session = sf.OpenSession())
{
    new SchemaExport(config).Execute(false, true, false, session.Connection, null);

    var obj = new InheritingClass
    {
        Keypart1 = 1,
        Keypart2 = 2,
    };

    session.Save(obj);
    session.Flush();
    session.Clear();

    // throws here
    var result = session.CreateCriteria<InheritingClass>().List<InheritingClass>();
}
abstract class BaseClass
{
    public virtual BaseClassId Key { get; set; }
}

class BaseClassId
{
    public virtual int Keypart1 { get; set; }
    public virtual int Keypart2 { get; set; }

    public override bool Equals(object obj)
    {
        var other = obj as BaseClassId;
        return (other != null) && (Keypart1 == other.Keypart1) && (Keypart2 == other.Keypart2);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return Keypart1 + Keypart2;
        }
    }
}

// mapping
CompositeId(b => b.Key)
    .KeyProperty(x => x.Keypart1)
    .KeyProperty(x => x.Keypart2);


var obj = new InheritingClass
{
    Key = new BaseClassId
    {
        Keypart1 = 1,
        Keypart2 = 2,
    }
};