gpt4 book ai didi

nhibernate - 如何映射枚举类而不将鉴别器传递到构造函数中?

转载 作者:行者123 更新时间:2023-12-02 05:16:22 25 4
gpt4 key购买 nike

基于Jimmy's Enumeration classes我想看看我是否可以避免using the constructor to instantiate my type (我认为这是与鉴别器值一起发生的)而是使用“工厂方法”式的方式从数据库映射我的实例。

这是我的类型:

public class Impact : Enumeration
{
public static readonly Impact Carbon
= new Impact(1, "Carbon dioxide equivalent", CommonUnit.CO2e);
public static readonly Impact Energy
= new Impact(2, "Energy", CommonUnit.MJ);
public static readonly Impact Cost
= new Impact(3, "Cost", CommonUnit.Dollars);



public Impact(int index, string name, CommonUnit unit)
: base(index, name)
{
this.Unit = unit;
}


public CommonUnit Unit { get; private set; }

}

这是枚举的定义:

public class Enumeration : ValueObject
{
public Enumeration(int index, string displayName)
{
this.Index = index;
this.DisplayName = displayName;
}


public int Index { get; private set; }
public string DisplayName { get; private set; }


public override string ToString()
{
return this.DisplayName;
}


public static IEnumerable<T> GetAllFor<T>() where T : Enumeration
{
foreach (var publicStatic in typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly))
{
Enumeration item = null;
item = (Enumeration)publicStatic.GetValue(null);
yield return item as T;
}
}

public static T With<T>(int index) where T : Enumeration
{
return GetAllFor<T>().SingleOrDefault(i => i.Index == index);
}
}

ValueObject 只是覆盖了平等功能。

在其他地方,我使用静态方法从该枚举中获取项目(有点像如何使用核心枚举静态方法):

impact = Impact.With<Impact>(index.ImpactId.Value);

这非常方便,但我想知道在重新水化对象时是否可以让 NHibernate 也执行此操作。

可以做到吗?如何做到?

最佳答案

使用 NHibernate 自定义类型:

public class EnumerationType<T> : PrimitiveType where T : Enumeration
{
public EnumerationType()
: base(new SqlType(DbType.Int32))
{
}

public override object Get(IDataReader rs, int index)
{
object o = rs[index];
var value = Convert.ToInt32(o);
return Enumeration.With<T>(value);
}

public override object Get(IDataReader rs, string name)
{
int ordinal = rs.GetOrdinal(name);
return Get(rs, ordinal);
}

public override Type ReturnedClass
{
get { return typeof(T); }
}

public override object FromStringValue(string xml)
{
return int.Parse(xml);
}

public override string Name
{
get { return "Enumeration"; }
}

public override void Set(IDbCommand cmd, object value, int index)
{
var parameter = (IDataParameter)cmd.Parameters[index];

var val = (Enumeration)value;

parameter.Value = val.Value;
}

public override string ObjectToSQLString(object value, Dialect dialect)
{
return value.ToString();
}

public override Type PrimitiveClass
{
get { return typeof(int); }
}

public override object DefaultValue
{
get { return 0; }
}
}

如果您正在进行基于 HBM.xml 的映射,则可以像这样设置自定义类型:

<property name="Impact" column="Impact" type="Namespace.To.EnumerationType`1[[Impact, AssemblyWithDomainEnum]], AssemblyWithNHibCustomType"/>

或者,如果您使用 Fluent NHibernate,则可以创建一个约定来映射所有枚举类型,而无需单独配置每个枚举类型:

public class EnumerationTypeConvention : IPropertyConvention, IPropertyConventionAcceptance
{
private static readonly Type _openType = typeof(EnumerationType<>);

public void Apply(IPropertyInstance instance)
{
var closedType = _openType.MakeGenericType(instance.Property.PropertyType);

instance.CustomType(closedType);
}

public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
criteria.Expect(x => typeof(Enumeration).IsAssignableFrom(x.Property.PropertyType));
}
}

然后在 Fluent NHibernate 配置中添加您喜欢的约定。

关于nhibernate - 如何映射枚举类而不将鉴别器传递到构造函数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10393311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com