【问题标题】:NHibernate, SQL Server - enum to int mappingNHibernate,SQL Server - 枚举到整数映射
【发布时间】:2011-04-11 21:02:23
【问题描述】:

我有一个类,它有一个枚举类型,指示消息类型是电子邮件还是短信。枚举类型定义:

public enum ReminderType
{
    Email = 1,
    Sms = 2
}

使用这种类型的类如下所示:

public class Reminder : EntityBase
{
    public virtual string Origin { get; set; }
    public virtual string Recipient { get; set; }
    public virtual ReminderType Type { get; set; }
    public virtual Business Business { get; set; }
    public virtual DateTime Created { get; set; }

    public Reminder()
    {
        Created = DateTime.UtcNow;
    }
}

但是,当我尝试将 Reminder 类型的实体持久保存到数据库时,我收到以下错误:

System.Data.SqlClient.SqlException (0x80131904): Conversion failed when converting the nvarchar value 'Email' to data type int.

支持字段的类型为int,所以我不确定NHibernate 为什么默认尝试映射字符串表示。我用的是Fluent NHibernate,相关的映射代码是:

mappings.Override<Reminder>(map =>
{
     map.Map(x => x.Type).Column("Type")
});

我很确定 NHibernate 的默认行为是将枚举映射为整数,那么为什么在这种情况下不这样做呢?如果这很重要,我正在使用 SQL Server 2005。

【问题讨论】:

标签: sql-server-2005 nhibernate fluent-nhibernate


【解决方案1】:

我正在做同样的事情并且让它像这样工作......

在我的例子中,EmployeeType 是枚举类

 Map(x => x.EmployeeType, "EmployeeType_Id").CustomType(typeof (EmployeeType));

【讨论】:

  • 如果我想在特定属性的基础上做这将是完美的。
【解决方案2】:

我不知道为什么这个人一直发帖然后删除他们的评论或答案,但他们提供的链接 () 确实回答了我的问题。我选择不对约定使用完整的类定义,而是在映射代码中使用内联约定,如下所示:

var mappings = AutoMap.AssemblyOf<Business>()
    .Where(x => x.IsSubclassOf(typeof(EntityBase)))
    .IgnoreBase(typeof(EntityBase))
    .Conventions.Add
    (
        ConventionBuilder.Id.Always(x => x.GeneratedBy.Identity()),
        ConventionBuilder.HasMany.Always(x => x.Cascade.All()),
        ConventionBuilder.Property.Always(x => x.Column(x.Property.Name)),
        Table.Is(o => Inflector.Pluralize(o.EntityType.Name)),
        PrimaryKey.Name.Is(o => "Id"),
        ForeignKey.EndsWith("Id"),
        DefaultLazy.Always(),
        DefaultCascade.All(),

        ConventionBuilder.Property.When(
            c => c.Expect(x => x.Property.PropertyType.IsEnum),
            x => x.CustomType(x.Property.PropertyType))
    );

最后一个约定生成器语句起到了作用。我很好奇为什么 Fluent NHibernate 现在默认将枚举映射为字符串。这似乎没有多大意义。

【讨论】:

  • 当您将枚举映射为 int 时,只有该应用程序(定义了枚举)知道它在数据库中的含义。这就像数据库中的一个神奇数字......
  • 对不起,我删除了第一条评论,因为在重新阅读代码后意识到我犯了错误并且评论不相关,第二条似乎很明显,因为它是第一个谷歌点击,所以我想你已经看过了。
  • @dotjoe:这听起来很合理。不过,我曾使用过相反的库的早期版本(默认情况下映射为 int 而不是字符串),因此这种行为改变开始像它一样开始出现是令人难以置信的混乱。
【解决方案3】:

你不应该在 NHibernate 中将 Enum 映射为 int。这成为拥有ghost updates 的原因。

最好的方法就是不在 XML 映射中设置类型属性。要在 Fluent NHibernate 中实现这一点,您可以使用 .CustomType(string.Empty)

您可以找到一些其他信息here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多