質問はそれをすべて言っています、デフォルトはstring
としてマップすることですが、int
としてマップする必要があります。
私は現在、PersistenceModel
を使用して、慣習を設定します。前もって感謝します。
更新トランクから最新バージョンのコードにアクセスすることで問題が解決したことがわかりました。
この規則を定義する方法は時々前に変更されましたが、今では:
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);
}
}
そのため、前述のように、最新バージョンのFluent NHibernateをトランクから削除すると、必要な場所に到達しました。最新のコードを持つ列挙型のマッピング例は次のとおりです。
Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));
カスタムタイプは、GenericEnumMapper<TEnum>
を使用するのではなく、enumのインスタンスとして処理することを強制します。
文字列を保持する列挙型マッパーと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);
このようにFluent NHibernateマッピングに規則を追加します。
Fluently.Configure(nHibConfig)
.Mappings(mappingConfiguration =>
{
mappingConfiguration.FluentMappings
.ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
})
./* other configuration */
ヌル可能列挙型を忘れないでください(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);
}
}
これは、列挙型プロパティをint値にマッピングした方法です。
Map(x => x.Status).CustomType(typeof(Int32));
私のために働く!
Fluent NHibernateとAutomapping(および潜在的にIoCコンテナー)を使用している場合:
IUserTypeConvention
は@Julienの上記の答え: 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);
}
}
Fluent NHibernate Automapping構成は、次のように構成できます。
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とインストーラーを使用)。 *
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => CreateSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest()
);
DBテーブルでは、値をint/tinyintのままにしておく必要があります。列挙型をマッピングするには、マッピングを正しく指定する必要があります。以下のマッピングおよび列挙サンプルを参照してください。
マッピングクラス
public class TransactionMap:ClassMap Transaction { public TransactionMap() { //その他のマッピング .... 。 //enum Map(x => x.Status、 "Status")。CustomType(); Table( "Transaction")のマッピング; } }
列挙
public enum TransactionStatus { Waiting = 1、 Processed = 2、 RolledBack = 3、 Blocked = 4 払い戻し= 5、 AlreadyProcessed = 6、 }
NHibernate IUserType
を作成し、プロパティマップでCustomTypeIs<T>()
を使用して指定できます。