我有一个自定义用户类型,用于使用Fluent NHibernate从数据库中的十进制值映射到实体上的属性。对象的映射工作正常,但我不知道如何动态更改十进制sql数据类型的精度和比例,以便我可以在不同的类映射中使用不同的精度和比例。
以下是我的自定义类型的示例;
public struct MyCustomType
{
private readonly decimal value;
public MyCustomType(decimal value)
{
this.value = value;
}
public static implicit operator MyCustomType(decimal value)
{
return new MyCustomType(value);
}
public static implicit operator decimal(MyCustomType value)
{
return value.value;
}
public string ToString(string format, IFormatProvider provider)
{
return value.ToString(format, provider);
}
}
这就是我在做用户类型的方式。
public class MyCustomUserType : IUserType
{
...
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
MyCustomType customType = (decimal)rs[names[0]];
return customType;
}
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
var parameter = (IDataParameter)cmd.Parameters[index];
parameter.Value = (decimal)(MyCustomType)value;
}
...
public SqlType[] SqlTypes
{
//I think I could hard code the precision and scale here
get { return new[] { SqlTypeFactory.Decimal }; }
}
public Type ReturnedType
{
get { return typeof(MyCustomType); }
}
public bool IsMutable
{
get { return true; }
}
}
最后这就是我映射对象的方式
public class SomeObjectMappingBase: ClassMap<SomeObject>
{
protected SomeObjectMappingBase()
{
//Currently I do this
Map(x => x.CustomTypeField).CustomType<MyCustomUserType>();
//I would like to be able to do this but it does not work
Map(x => x.CustomTypeField).CustomType<MyCustomUserType>().Scale(10).Precision(20);
}
}
答案 0 :(得分:2)
您可以为每个精度和比例组合实现IParameterizedUserType或子类MyCustomUserType。
更新:不幸的是,我想不出一种启用语法.CustomType<SomeObject>().Scale(x).Precision(y)
的方法。代替
选项1到子类
class MyCustomUserTypeFor10And20 : MyCustomUserType
{
public override SqlType[] SqlTypes
{
get { return new[] { SqlTypeFactory.GetDecimal(10, 20) }; }
}
}
Map(x => x.CustomTypeField).CustomType<MyCustomUserTypeFor10And20>();
选项2 parameterizedType
<property name="CustomProperty">
<type name="MyCustomUserType">
<param name="precision">10</param>
<param name="scale">20</param>
</type>
</property>
class MyCustomUserType : IParameterizedType
{
public void SetParameterValues(IDictionary<string, string> parameters)
{
precision = parameter["precision"];
scale = parameter["scale"];
}
}
选项3以某种方式使用它:不要映射自定义类型,但在配置
上设置它var mapping = config.GetClassMapping(typeof(...));
foreach (var prop in mapping.PropertyIterator.Where(p => p.Type.ReturnedClass == typeof(decimal)))
{
prop.Type = new CustomType(typeof(MyCustomType), new Dictionary<string, string>
{
{ "precision", prop.Type.SqlTypes(null)[0].Precision },
{ "scale", prop.Type.SqlTypes(null)[0].Precision }
});
}