.net 使用流畅的 nhibernate 映射枚举
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1483044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mapping enum with fluent nhibernate
提问by Puneet
I am following the http://wiki.fluentnhibernate.org/Getting_startedtutorial to create my first NHibernate project with Fluent NHibernate
我正在按照http://wiki.fluentnhibernate.org/Getting_started教程使用 Fluent NHibernate 创建我的第一个 NHibernate 项目
I have 2 tables
我有2张桌子
1) Account with fields
1) 有字段的帐户
Id
AccountHolderName
AccountTypeId
2) AccountType with fields
2) 带字段的 AccountType
Id
AccountTypeName
Right now the account types can be Savings or Current So the table AccountTypes stores 2 rows 1 - Savings 2 - Current
现在帐户类型可以是 Savings 或 Current 所以表 AccountTypes 存储 2 行 1 - Savings 2 - Current
For AccoutType table I have defined enum
对于 AccoutType 表,我定义了枚举
public enum AccountType {
Savings=1,
Current=2
}
For Account table I define the entity class
对于 Account 表,我定义了实体类
public class Account {
public virtual int Id {get; private set;}
public virtual string AccountHolderName {get; set;}
public virtual string AccountType {get; set;}
}
The fluent nhibernate mappings are:
流畅的 nhibernate 映射是:
public AgencyMap() {
Id(o => o.Id);
Map(o => o.AccountHolderName);
Map(o => o.AccountType);
}
When I try to run the solution, it gives an exception - InnerException = {"(XmlDocument)(2,4): XML validation error: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has incomplete content. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'ur...
当我尝试运行该解决方案时,它给出了一个异常 - InnerException = {"(XmlDocument)(2,4): XML 验证错误:命名空间 'urn:nhibernate-mapping-2.2' 中的元素 'class' 内容不完整。预期的可能元素列表:命名空间 'ur...
I guess that is because I have not speciofied any mapping for AccountType.
我想这是因为我没有为 AccountType 指定任何映射。
The questions are:
问题是:
- How can I use AccountType enum instead of a AccountType class?
- Maybe I am going on wrong track. Is there a better way to do this?
- 如何使用 AccountType 枚举而不是 AccountType 类?
- 也许我走错了路。有一个更好的方法吗?
Thanks!
谢谢!
回答by Dan
The following apparently no longer works https://stackoverflow.com/a/503327/189412
以下显然不再有效https://stackoverflow.com/a/503327/189412
How about just doing this:
只是这样做怎么样:
public AgencyMap() {
Id(o => o.Id);
Map(o => o.AccountHolderName);
Map(o => o.AccountType).CustomType<AccountType>();
}
The custom type handles everything :)
自定义类型处理一切:)
回答by mhenrixon
public class Account {
public virtual int Id {get; private set;}
public virtual string AccountHolderName {get; set;}
public virtual AccountType AccountType {get; set;}
}
public AgencyMap() {
Id(o => o.Id);
Map(o => o.AccountHolderName);
Map(o => o.AccountType);
}
Fluent NHibernate saves enum values as string by default if you want to override that you need to supply a convention for it. Something like:
Fluent NHibernate 默认将枚举值保存为字符串,如果您想覆盖需要为其提供约定的内容。就像是:
public class EnumConvention :
IPropertyConvention,
IPropertyConventionAcceptance
{
#region IPropertyConvention Members
public void Apply(IPropertyInstance instance)
{
instance.CustomType(instance.Property.PropertyType);
}
#endregion
#region IPropertyConventionAcceptance Members
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)
);
}
#endregion
}
Almost forgot that you need to add the convention to your fluent config as well. You do that at the same place you add the mappings:
几乎忘记了您还需要将约定添加到流畅的配置中。您在添加映射的同一位置执行此操作:
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<BillingRecordMap>()
.Conventions.AddFromAssemblyOf<EnumConvention>()
回答by Igor Monteiro
A Great way to do this, is implement the interface IUserType and Create a CustomType with the rules to write and read, that′s a example to boolean:
一个很好的方法是实现接口 IUserType 并创建一个带有写入和读取规则的 CustomType,这是布尔值的示例:
public class CharToBoolean : IUserType
{
public SqlType[] SqlTypes => new[] { NHibernateUtil.String.SqlType };
public Type ReturnedType => typeof(bool);
public bool IsMutable =>true;
public object Assemble(object cached, object owner)
{
return (cached);
}
public object DeepCopy(object value)
{
return (value);
}
public object Disassemble(object value)
{
return (value);
}
public new bool Equals(object x, object y)
{
if (ReferenceEquals(x, y)) return true;
var firstObject = x as string;
var secondObject = y as string;
if (string.IsNullOrEmpty(firstObject) || string.IsNullOrEmpty(secondObject)) return false;
if (firstObject == secondObject) return true;
return false;
}
public int GetHashCode(object x)
{
return ((x != null) ? x.GetHashCode() : 0);
}
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
var obj = NHibernateUtil.String.NullSafeGet(rs, names[0]);
if (obj == null) return null;
var value = (string)obj;
return value.ToBoolean();
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
if(value != null)
{
if ((bool)value)
{
((IDataParameter)cmd.Parameters[index]).Value = "S";
}
else
{
((IDataParameter)cmd.Parameters[index]).Value = "N";
}
}
else
{
((IDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
}
}
public object Replace(object original, object target, object owner)
{
return original;
}
}
}
}
the mapping:
映射:
this.Map(x => x.DominioGenerico).Column("fldominiogen").CustomType<CharToBoolean>();
It′s a sample but you can do this with other types.
这是一个示例,但您可以使用其他类型执行此操作。

