流畅的NHibernate错误:实体'ClassMap`1'没有映射的Id

Chr*_*ris 4 .net c# nhibernate fluent-nhibernate

我正在将之前的项目从使用普通的NHibernate hbm.xml映射转换为Fluent NHibernate.目前,我仍然坚持要实现这一目标的最后步骤之一.我为DefaultAutomappingConfiguration添加了一个派生类来修改我的ID命名约定.字符串"Id"附加到类名称:

    public override bool IsId(FluentNHibernate.Member member)
    {
        return member.Name == member.DeclaringType.Name + "Id";
    }
Run Code Online (Sandbox Code Playgroud)

这应该使"代理商"在名为"AgencyId"的字段中具有ID.相反,我收到此错误:

The entity 'ClassMap`1' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id).
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
Run Code Online (Sandbox Code Playgroud)

我在IsId函数上创建了一个断点,看看发生了什么:

{Property: Cache}
{Name = "ClassMap`1" FullName = "FluentNHibernate.Mapping.ClassMap`1[[BackendDb.Model.Agency, BackendDb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"}
Run Code Online (Sandbox Code Playgroud)

这是什么?对象不是我创造的东西.每个其他对象都通过这个函数很好,而我实际想要映射的对象返回正确的值.

我的Session工厂看起来像这样:

var cfg = new MapConfig();
return Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(m => m.Server(@".\SqlExpress")
    .Database("{some dbname}")
    .TrustedConnection()))
.Mappings(m =>
    m.AutoMappings
        .Add(AutoMap.AssemblyOf<Agency>(cfg))
)
.BuildSessionFactory();
Run Code Online (Sandbox Code Playgroud)

令人讨厌的是,似乎这在某种程度上导致我在我的开发数据库中测试Fluent NHibernate的三个表被清空.我勒个去?

cod*_*ion 7

sessionfactory试图Agency根据这个指令自动化包含你的类的程序集中的所有类:Add(AutoMap.AssemblyOf<Agency>(cfg)).由于您AgencyMap在程序集中有一个并且ClassMap<>没有Id属性,因此FNH会抛出错误.

如果要使用ClassMap<>配置,而不是(或除此之外)声明自动化配置,请声明一个流畅的映射:

m.FluentMappings.AddFromAssemblyOf<Agency>();
Run Code Online (Sandbox Code Playgroud)

如果您不需要AutoMappings,请删除`.AutoMappings.Add'指令.

但是,如果要使用AutoMappings,则需要告诉FNH要映射的类.为了解决这个问题,我通常会定义一个标记界面:

public abstract class Entity : IPersistable
{
    public virtual int Id { get; set; }
}

public interface IPersistable
{
}
Run Code Online (Sandbox Code Playgroud)

然后,在我派生的类中DefaultAutomappingConfiguration,我告诉FNH只映射具有该接口的类(您可以限制映射的类,但是您认为合适):

public class EntityAutoMappingConfiguration : DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        return type.GetInterfaces().Contains(typeof (IPersistable));
    }

}
Run Code Online (Sandbox Code Playgroud)

为了处理主键映射,我创建了一个约定类:

public class PrimaryKeyNamePlusId : IIdConvention 
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.EntityType.Name+"Id");
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我将SessionFactory配置为使用配置/约定类:

 m.AutoMappings.AssemblyOf<Entity>(new EntityAutoMappingConfiguration())
            .IgnoreBase<Entity>()
            .UseOverridesFromAssemblyOf<Entity>()
            .Conventions.AddFromAssemblyOf<Entity>();
Run Code Online (Sandbox Code Playgroud)