我有以下(简化)
public enum Level
{
Bronze,
Silver,
Gold
}
public class Member
{
public virtual Level MembershipLevel { get; set; }
}
public class MemberMap : ClassMap<Member>
{
Map(x => x.MembershipLevel);
}
这将创建一个包含名为MembershipLevel的列的表,其值为Enum字符串值。
我想要的是将整个枚举创建为查找表,其中成员表以整数值作为FK引用它。
另外,我想在不改变模型的情况下这样做。
答案 0 :(得分:20)
要将枚举属性映射为int列,请使用方法CustomType
。
public class MemberMap : ClassMap<Member>
{
Map( x => x.MembershipLevel ).CustomType<int>();
}
为了使enum和lookup表保持同步,我会将查找表和数据添加到sql脚本中。集成测试可以验证枚举和查找表值是否相同。
如果您希望SchemaExport创建此表,请为其添加类和映射。
public class MembershipLevel
{
public virtual int Id { get; set; }
public virtual string Code { get; set; }
}
public class MembershipLevelMap : ClassMap<MembershipLevel>
{
Id( x => x.Id );
Map( x => x.Code );
}
如果要使用SchemaExport创建表,则还需要填充它:
foreach (Level l in Enum.GetValues( typeof( Level ))) {
session.Save( new MembershipLevel{ Id = (int) l, Code = l.ToString() });
}
答案 1 :(得分:5)
我不这样做,因为你的Enum声明不是动态的,或者更简单,它不会在不重新编译的情况下改变,而你的查找表可能随时改变。如果枚举和查找表的值不匹配,那么下一步是什么?
另一个原因是如果更改枚举(在代码中),则必须将其与数据库表同步。由于Enums没有增量密钥(PK),因此它们无法如此简单地同步。假设您从代码中删除一个Enum成员并重新编译它,应该发生什么?如果你改变一个值?
我希望我明确反对这种方法。所以我强烈建议存储枚举成员的名称或值。要按名称存储它,只需这样映射:
public class MemberMap : ClassMap<Member>
{
Map(x => x.MembershipLevel, "level")
.CustomType<GenericEnumMapper<Level>>()
.Not.Nullable();
}
要存储这些值,请按@Lachlan的答案发布。
或者,如果您确实需要查找表并希望使用带有严格检查的枚举,请使用 PK 创建一个普通模型(或使用此值), KEY 和 VALUE 。使用静态成员创建枚举,并在启动时让应用程序在数据库中查询名称和值。如果事情不匹配,做任何你需要的事情。此外,这并不能保证您的程序在程序运行时不会更改,所以最好不要确保它不会。