我正在尝试使用Fluent NHibernate映射NHibernate中的枚举集合,然后对该枚举集合的内容执行查询,但系统每次都会抛出异常。
我有一个Widget类,映射到Widget表。还有一个WidgetType枚举,Widget的单个实例可以有许多WidgetTypes,通过WidgetTypes属性进行映射。该属性需要映射到一个单独的表WidgetTypeRef,它有两个整数列:WidgetId和WidgetType。
public class Widget
{
/* omitted */
public IList<WidgetType> WidgetTypes { get; set; }
}
public enum WidgetType
{
SomeType = 0,
SomeOtherType = 1,
YetOneMoreType = 2
}
public partial class WidgetMapping : IAutoMappingOverride<Widget>
{
public void Override(AutoMapping<Widget> mapping)
{
/* omitted */
mapping.HasMany(w => w.WidgetTypes)
.Table("WidgetTypeRef")
.KeyColumn("WidgetId")
.Element("WidgetType");
}
}
我无法控制数据库架构;架构无法更改。模式必须存储与Widget关联的WidgetTypes的整数值,并且不能转换为与枚举的字符串版本匹配。我非常想保持枚举的强类型,并且避免为Ref表创建一个新的实体。
其他类具有基于枚举的类型属性,可以使用“.CustomType(typeof(someTypeEnum)”配置,但HasMany映射上没有CustomType属性。使用上面的HasMany映射,对集合的查询会抛出“无法确定成员类型“例外。
这甚至可能吗?该房产应该如何设置?如何配置Fluent映射?如何查询集合(我的查询只需要等同于Any或Contains)?
答案 0 :(得分:2)
public class EnumToIntConvention : IUserTypeConvention
{
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
criteria.Expect(x => x.Property.PropertyType.IsEnum);
}
public void Apply(IPropertyInstance target)
{
target.CustomType(target.Property.PropertyType);
}
}
使用该约定,具有以下枚举:
public enum Status
{
Inactive = 0,
Active = 1,
Canceled = 2
}
并像这样设置(也应该使用Fluent映射):
var cfg = Fluently.Configure()
.Database(configurer)
.Mappings(m =>
{
m.AutoMappings.Add(AutoMap.Assemblies(Assembly.GetExecutingAssembly())
.Where(type => AutomapAssemblies.Contains(type.Namespace))
.Conventions.Add<EnumToIntConvention>() // Magic code goes here!
.Conventions.Add());
});
将保存integer
值而不是string
值。