c# - 为什么 Fluent 的 NHibernate 的 AutoMapping 会忽略枚举类型?

标签 c# nhibernate fluent-nhibernate fluent-nhibernate-mapping .net-4.6

我有以下枚举类型:

public enum EnumType
{
    E1,
    E2
}

在下面的类中使用:

public class X
{
    public virtual int? Id { get; set; }

    public virtual EnumType EnumProperty { get; set; }

    public virtual string S { get; set; }
}

我想使用 NHibernate 将这种类型的实例持久保存在数据库中。为了避免编写样板代码,我正在尝试使用自动映射功能,如下所示:

private ISessionFactory CreateSessionFactory()
{
    var mappings = AutoMap
        .AssemblyOf<Domain.X>(new MyAutoMappingConfiguration());

    this.NHibernateConfiguration = Fluently
        .Configure()
        .Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2012.ConnectionString(
                b => b.FromConnectionStringWithKey("x")))
        .Mappings(m => m.AutoMappings.Add(mappings))
        .BuildConfiguration();

    return this.NHibernateConfiguration.BuildSessionFactory();
}

MyAutoMappingConfiguration 看起来像这样:

public class MyAutoMappingConfiguration: FluentNHibernate.Automapping.DefaultAutomappingConfiguration
{
    public override bool ShouldMap(Type type)
    {
        return type.Namespace == "Domain";
    }

    public override bool IsComponent(Type type)
    {
        return type.Name == "EnumType";
    }
}

当我使用从此配置生成的模式创建数据库时:

new SchemaExport(this.sessionProvider.NHibernateConfiguration)
    .Execute(true, true, false);

正在生成并执行以下脚本:

if exists (select * from dbo.sysobjects where id = object_id(N'[X]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [X]

create table [X] (
    Id INT not null,
   S NVARCHAR(255) null,
   primary key (Id)
)

为什么忽略属性 EnumProperty

当我为 X 添加一个显式映射时,或者(看起来等价的)像这样的自动映射覆盖:

var mappings = AutoMap
    .AssemblyOf<Domain.X>(new MyAutoMappingConfiguration())
    .Override<Domain.X>(m =>
    {
        m.Table("X");
        m.Id(x => x.Id);
        m.Map(x => x.EnumProperty);     // this works
        m.Map(x => x.S);
    });

脚本正确生成:

if exists (select * from dbo.sysobjects where id = object_id(N'[X]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [X]

create table [X] (
    Id INT not null,
   EnumProperty NVARCHAR(255) null,
   S NVARCHAR(255) null,
   primary key (Id)
)

这表明 NHibernate 正确映射呈现的枚举的能力似乎没有任何问题。为什么自动映射不能解决这个问题?


当我将以下方法添加到 MyAutoMappingConfiguration 时:

public override bool ShouldMap(Member member)
{
    var result = base.ShouldMap(member);
    return result;
}

并放置断点,对于 EnumProperty 成员,resulttrue,稍后会以某种方式被忽略。

最佳答案

根据我的经验,枚举是开箱即用的,根本不需要做任何额外的事情(没有自定义类型或组件)。

所以,有两个问题:

  • IsComponent 不应指示所讨论的枚举是一个组件:

    public override bool IsComponent(Type type)
    {
        return base.IsComponent(type);
    }
    

    (或完全删除实现)

  • ShouldMap 不应指示枚举需要显式映射。无论如何它都会被映射,因为它是一个属性。所以,例如:

    public override bool ShouldMap(Member member)
    {
        return base.ShouldMap(member) && member.CanWrite &&
               !member.MemberInfo.IsDefined(typeof(NotMappedAttribute), false);
    }
    

    在你的例子中,如果枚举在同一个命名空间中,你应该这样做:

    public override bool ShouldMap(Type type)
    {
        return type.Namespace == "Domain"
            && !type.IsEnum;
    }
    

    (这有点违反直觉)

关于c# - 为什么 Fluent 的 NHibernate 的 AutoMapping 会忽略枚举类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34667082/

相关文章:

c# - 使用 SmsManager 打开默认的短信应用

c# - 使用 NHibernate 编写单元测试的最佳实践

asp.net-mvc - 什么会导致 NHibernate 的 Save 方法无提示地失败?

nhibernate - 在组件集合中映射组件

join - Fluent NHibernate - 将属性映射到连接表上的列

c# - 我怎样才能使这段代码更通用

c# - x :FieldModifier is not valid for the language C#?

C# 多态属性

NHibernate:HQL:从日期字段中删除时间部分

c# - 通过代码零或一关系映射