2011-04-11 136 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