我下面的http://wiki.fluentnhibernate.org/Getting_started教程与功能NHibernate创建我的第一个项目的NHibernate
我有2个表
1)字段帐户
Id
AccountHolderName
AccountTypeId
2)用ACCOUNTTYPE字段
Id
AccountTypeName
眼下账户类型可以是储蓄或电流,使表AccountTypes店2行1 - 2储蓄 - 当前
对于AccoutType表我已经定义枚举
public enum AccountType {
Savings=1,
Current=2
}
对于帐户表我定义的实体类
public class Account {
public virtual int Id {get; private set;}
public virtual string AccountHolderName {get; set;}
public virtual string AccountType {get; set;}
}
该功能NHibernate映射是:
public AgencyMap() {
Id(o => o.Id);
Map(o => o.AccountHolderName);
Map(o => o.AccountType);
}
当我尝试运行解决方案,它提供了一个异常 - 的InnerException = {“(XmlDocument的)(2,4):XML验证错误:元素‘类’在命名空间‘瓮:NHibernate的映射-2.2’具有不完整的内容。可能元素的列表预计:“元,子查询,高速,同步,评论,的tuplizer,ID,复合ID”命名空间“UR ...
我想这是因为我还没有speciofied为ACCOUNTTYPE任何映射。
这些问题是:
- 我如何使用ACCOUNTTYPE枚举,而不是ACCOUNTTYPE类的?
- 也许我会在错误的轨道。 有一个更好的方法吗?
谢谢!
下面显然不再适用https://stackoverflow.com/a/503327/189412
如何只这样做:
public AgencyMap() {
Id(o => o.Id);
Map(o => o.AccountHolderName);
Map(o => o.AccountType).CustomType<AccountType>();
}
自定义类型处理一切:)
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);
}
功能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
}
差点忘了,你需要的约定添加到您流畅的配置也是如此。 你这样做,在同一个地方,你添加映射:
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<BillingRecordMap>()
.Conventions.AddFromAssemblyOf<EnumConvention>()
一个伟大的方式做到这一点,是实现接口IUserType和创建的规则CustomType写入和读取,that'sa例如布尔:
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;
}
}
}
映射:
this.Map(x => x.DominioGenerico).Column("fldominiogen").CustomType<CharToBoolean>();
It'sa样品,不过你可以用其他类型的做到这一点。