2011-04-11 123 views
6

我有一个类具有枚举类型,指示消息类型是电子邮件或短信。枚举类型定义:NHibernate,SQL Server的 - 枚举到int映射

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; 
    } 
} 

当我尝试但是坚持式提醒实体到数据库中,我得到以下错误:

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

支持字段是int型的,所以我不知道为什么NHibernate的是试图映射默认字符串表示。我使用功能NHibernate,以及相关的映射代码:

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

我敢肯定的NHibernate的默认行为是映射枚举为int,那么,为什么在此情况下,这样做?如果有问题,我正在使用SQL Server 2005。

+0

Email是Type属性的字符串值。 Nhibernate应该试图存储它作为整数值1,但它试图存储字符串'电子邮件',而不是,因此错误。我不知道它为什么这样做,虽然... – Chris 2011-04-11 21:10:23

+0

http://stackoverflow.com/questions/439003/how-do-you-map-an-enum-as-an-int-value-with-fluent- nhibernate – dotjoe 2011-04-11 21:37:01

+0

或http://stackoverflow.com/questions/1483044/mapping-enum-with-fluent-nhibernate – 2011-04-12 08:51:27

回答

3

我不知道为什么这个人不断发布,然后删除他们的评论或答案,但他们提供的链接()确实回答我的问题。我选择不走一个完整的打击类定义的惯例,而是内嵌公约中的映射代码,就像这样:

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)) 
    ); 

最后大会建设者声明的伎俩。我很好奇为什么流利NHibernate的默认是现在将枚举映射为字符串。这似乎没有多大意义。

+1

将枚举映射为int时,只有该应用程序(它定义了枚举)知道它在数据库中的含义。这就像数据库中的幻数... – dotjoe 2011-04-11 21:42:16

+0

对不起,我删除了第一条评论,因为重新阅读代码后意识到我犯了错误,评论与此无关,第二条看起来很明显,因为它是第一个谷歌命中之一,所以我想你已经看到了它。 – R0MANARMY 2011-04-11 22:04:03

+0

@dotjoe:这听起来很合理。我曾经使用过早期版本的库,但是却做了相反的事情(默认情况下映射为int而不是字符串),所以对于这种行为改变开始显示出来像是一样令人难以置信的混淆。 – Chris 2011-04-11 22:33:30

5

我做同样的事情,得到它的工作是这样的...

在我的情况EmployeeType是枚举类

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

这将是完美的,如果我曾经想要在一个特定的基础上做到这一点。 – Chris 2011-04-11 22:34:01

0

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

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

一些其他信息,你可以找到here