La question en dit long, la valeur par défaut est qu'elle mappe en tant que string
mais j'en ai besoin pour mapper en tant que int
.
J'utilise actuellement PersistenceModel
pour définir mes conventions si cela fait une différence. Merci d'avance.
Mise à jour J'ai trouvé que le fait d'accéder à la dernière version du code à partir du coffre a résolu mes problèmes.
La façon de définir cette convention a changé il y a quelque temps, c'est maintenant:
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);
}
}
Donc, comme mentionné, le fait de sortir la dernière version de Fluent NHibernate du coffre m'a amené là où je devais être. Un exemple de mappage pour une énumération avec le dernier code est:
Map(quote => quote.Status).CustomTypeIs(typeof(QuoteStatus));
Le type personnalisé le force à être traité comme une instance de l'énumération plutôt qu'à l'aide de GenericEnumMapper<TEnum>
.
J'envisage actuellement de soumettre un correctif pour pouvoir basculer entre un mappeur d'énumération qui persiste une chaîne et celui qui persiste un int car cela semble être quelque chose que vous devriez pouvoir définir en tant que convention.
Cela est apparu sur mon activité récente et les choses ont changé dans les nouvelles versions de Fluent NHibernate pour rendre cela plus facile.
Pour que toutes les énumérations soient mappées sous forme d'entiers, vous pouvez maintenant créer une convention comme ceci:
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;
}
}
Votre cartographie doit alors être:
Map(quote => quote.Status);
Vous ajoutez la convention à votre mappage Fluent NHibernate comme ceci;
Fluently.Configure(nHibConfig)
.Mappings(mappingConfiguration =>
{
mappingConfiguration.FluentMappings
.ConventionDiscovery.AddFromAssemblyOf<EnumConvention>();
})
./* other configuration */
N'oubliez pas les énumérations nullables (comme ExampleEnum? ExampleProperty
)! Ils doivent être vérifiés séparément. Voici comment cela se fait avec la nouvelle configuration de style 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);
}
}
voici comment j'ai mappé une propriété enum avec une valeur int:
Map(x => x.Status).CustomType(typeof(Int32));
travaille pour moi!
Pour ceux qui utilisent Fluent NHibernate avec Automapping (et potentiellement un conteneur IoC):
Le IUserTypeConvention
est comme @ la réponse de Julien ci-dessus: 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);
}
}
La configuration Fluent NHibernate Automapping peut être configurée comme suit:
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>();
});
}
* Ensuite, le CreateSessionFactory
peut être utilisé facilement dans un IoC tel que Castle Windsor (en utilisant un PersistenceFacility et un installateur). *
Kernel.Register(
Component.For<ISessionFactory>()
.UsingFactoryMethod(() => CreateSessionFactory()),
Component.For<ISession>()
.UsingFactoryMethod(k => k.Resolve<ISessionFactory>().OpenSession())
.LifestylePerWebRequest()
);
Vous devez conserver les valeurs int/tinyint dans votre table DB. Pour mapper votre énumération, vous devez spécifier le mappage correctement. Veuillez voir ci-dessous la cartographie et l'énumération de l'échantillon,
Classe de mappage
public class TransactionMap: ClassMap Transaction { public TransactionMap () { // Autres mappages .... . // Mappage pour l'énumération Carte (x => x.Status, "Status"). CustomType (); Table ("Transaction") ; } }
Enum
public enum TransactionStatus { En attente = 1, Traité = 2, RolledBack = 3, Bloqué = 4, Remboursé = 5, Déjà traité = 6, }
Vous pouvez créer un NHibernate IUserType
et le spécifier à l'aide de CustomTypeIs<T>()
sur la carte de propriétés.