2009-01-13 56 views
87

問題確實如此,默認情況下它會映射爲string,但我需要將其映射爲int如何將一個枚舉映射爲一個int值和流暢的NHibernate?

我目前使用PersistenceModel來設置我的約定,如果這有什麼區別。提前致謝。

更新 發現從中繼獲取最新版本的代碼解決了我的困境。

+4

如果你自己解決了這個問題,你應該回答這個問題,然後將其標記爲正確的回答以便將來的搜索者可以找到它。 – 2009-01-13 16:17:02

+0

你可以請發佈答案嗎? – mxmissile 2009-01-13 21:51:28

+0

完成傢伙。抱歉耽擱了。我真的不知道我應該怎麼處理這個問題,因爲我只需要最新版本的庫。 – 2009-01-14 08:46:36

回答

82

的方法來定義這個約定有時前改變了,它現在:

public class EnumConvention : IUserTypeConvention 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Property.PropertyType.IsEnum); 
    } 

    public void Apply(IPropertyInstance target) 
    { 
     target.CustomType(target.Property.PropertyType); 
    } 
} 
0

您可以創建NHibernate IUserType,並在屬性映射上使用CustomTypeIs<T>()指定它。

45

所以,如前所述,將最新版本的流利NHibernate從主幹中取出,讓我到了需要的地方。與最新的代碼中的枚舉的示例映射是:

Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus)); 

定製類型迫使它作爲枚舉的實例來處理,而不是使用GenericEnumMapper<TEnum>

我實際上正在考慮提交一個修補程序,以便能夠在保持字符串的枚舉映射器和保持int的枚舉映射器之間進行切換,因爲這看起來應該是您應該能夠設置爲約定的東西。


這出現在我最近的活動上,並且在新版本的Fluent NHibernate中,事情已經發生了變化,以使這更容易。

要使所有枚舉被映射爲整數,你現在就可以創造像這樣一個約定:

public class EnumConvention : IUserTypeConvention 
{ 
    public bool Accept(IProperty target) 
    { 
     return target.PropertyType.IsEnum; 
    } 

    public void Apply(IProperty target) 
    { 
     target.CustomTypeIs(target.PropertyType); 
    } 

    public bool Accept(Type type) 
    { 
     return type.IsEnum; 
    } 
} 

然後你的映射只有是:

Map(quote => quote.Status); 

您的約定添加到您的流利像這樣的NHibernate映射;

Fluently.Configure(nHibConfig) 
    .Mappings(mappingConfiguration => 
    { 
     mappingConfiguration.FluentMappings 
      .ConventionDiscovery.AddFromAssemblyOf<EnumConvention>(); 
    }) 
    ./* other configuration */ 
+3

,默認爲「int mode」。誰將枚舉持久化爲字符串? – 2009-02-17 10:40:18

40

不要忘記爲空的枚舉(如ExampleEnum? ExampleProperty)!他們需要分開檢查。這是它是如何與新的FNH風格的配置來完成:

public class EnumConvention : IUserTypeConvention 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Property.PropertyType.IsEnum || 
      (x.Property.PropertyType.IsGenericType && 
      x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && 
      x.Property.PropertyType.GetGenericArguments()[0].IsEnum) 
      ); 
    } 

    public void Apply(IPropertyInstance target) 
    { 
     target.CustomType(target.Property.PropertyType); 
    } 
} 
25

這是怎麼了,我映射一個枚舉屬性有一個int值:

Map(x => x.Status).CustomType(typeof(Int32)); 

對我的作品!

1

對於使用功能NHibernate與自動映射(以及潛在IoC容器)的那些:

IUserTypeConvention是@於連的回答以上:https://stackoverflow.com/a/1706462/878612

public class EnumConvention : IUserTypeConvention 
{ 
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
    { 
     criteria.Expect(x => x.Property.PropertyType.IsEnum); 
    } 

    public void Apply(IPropertyInstance target) 
    { 
     target.CustomType(target.Property.PropertyType); 
    } 
} 

的功能NHibernate自動映射配置可以像這樣配置:

protected virtual ISessionFactory CreateSessionFactory() 
    { 
     return Fluently.Configure() 
      .Database(SetupDatabase) 
      .Mappings(mappingConfiguration => 
       { 
        mappingConfiguration.AutoMappings 
         .Add(CreateAutomappings); 
       } 
      ).BuildSessionFactory(); 
    } 

    protected virtual IPersistenceConfigurer SetupDatabase() 
    { 
     return MsSqlConfiguration.MsSql2008.UseOuterJoin() 
     .ConnectionString(x => 
      x.FromConnectionStringWithKey("AppDatabase")) // In Web.config 
     .ShowSql(); 
    } 

    protected static AutoPersistenceModel CreateAutomappings() 
    { 
     return AutoMap.AssemblyOf<ClassInAnAssemblyToBeMapped>(
      new EntityAutomapConfiguration()) 
      .Conventions.Setup(c => 
       { 
        // Other IUserTypeConvention classes here 
        c.Add<EnumConvention>(); 
       }); 
    } 

*那麼CreateSessionFactory可以很容易地用於Castle Windsor等IoC(使用PersistenceFacility和installer)。 *

Kernel.Register(
     Component.For<ISessionFactory>() 
      .UsingFactoryMethod(() => CreateSessionFactory()), 
      Component.For<ISession>() 
      .UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession()) 
      .LifestylePerWebRequest() 
    ); 
0

您應該將值保存爲int/tinyint在您的數據庫表中。爲了映射你的枚舉,你需要正確指定映射。請參閱下面的映射和枚舉樣品,

映射類

 
public class TransactionMap : ClassMap Transaction 
{ 
    public TransactionMap() 
    { 
     //Other mappings 
     ..... 
     //Mapping for enum 
     Map(x => x.Status, "Status").CustomType(); 

     Table("Transaction"); 
    } 
} 

枚舉

 
public enum TransactionStatus 
{ 
    Waiting = 1, 
    Processed = 2, 
    RolledBack = 3, 
    Blocked = 4, 
    Refunded = 5, 
    AlreadyProcessed = 6, 
}
相關問題