Nhibernate:以相同的精度和比例映射所有小数

我理解在NHibernate中,使用代码映射,我可以指定十进制属性的精度和比例,如下所示:

Property( x => x.Dollars, m => { m.Precision(9); m.Scale(6); } ); 

这很好,但我想知道是否有一种方法可以轻松地以简单的方式映射所有类中的所有小数属性。 我必须仔细检查所有映射并手动更新每个映射,这似乎有点疯狂。 有谁知道如何实现这一目标?

BeforeMapProperty上使用BeforeMapProperty: –

 var mapper = new ModelMapper(); mapper.BeforeMapProperty += (inspector, member, customizer) => { if (member.LocalMember.GetPropertyOrFieldType() == typeof (decimal)) { customizer.Precision(9); customizer.Scale(6); } }; 

要添加的唯一其他内容是删除所有出现的: –

  m => { m.Precision(9); m.Scale(6); } 

来自您的映射类,因为这些将覆盖您在BeforeMapProperty设置的BeforeMapProperty除非您有其他具有不同比例或精度的小数。

您可以编写UserType 。 优点是您可以轻松区分不同类型的小数(您可能不希望所有小数都具有相同的精度)。

 Property( x => x.Dollars, m => m.Type() ); 

您需要付出一些努力将其放入所有货币属性中,但随后您将拥有更具可读性和自描述性的映射定义。


类似的解决方案(语法上),但更容易实现,是编写一个设置精度的扩展方法

 Property( x => x.Dollars, m => m.MapMoney() ); public static void MapMoney(this IPropertyMapper mapper) { m.Precision(9); m.Scale(6); } 

同样在这里:它使映射定义更具自我描述性。

(是的,我知道您不想更改所有文件,但我仍然建议将此信息放入映射文件中,因为它更明确的是十进制实际上是什么。很容易更改所有映射Money属性,但保留Amount属性。对于完全隐式的解决方案,请继续阅读。)


或者,您可以使用映射约定 。 这些非常强大。 您仍然可以覆盖映射文件中的精度,这提供了很大的灵活性。

 mapper.BeforeMapProperty += MapperOnBeforeMapProperty; private void MapperOnBeforeMapProperty( IModelInspector modelInspector, PropertyPath member, IPropertyMapper propertyCustomizer) { Type propertyType; // requires some more condition to check if it is a property mapping or field mapping propertyType = (PropertyInfo)member.LocalMember.PropertyType; if (propertyType == typeof(decimal)) { propertyCustomizer.Precision(9); propertyCustomizer.Scale(6); } } 

也可以将用户类型放入映射约定中,作为默认值

你能用FluentNHibernate吗? 它使您可以根据需要灵活地应用约定。 请看这里: https : //github.com/jagregory/fluent-nhibernate/wiki/Conventions和这里: http : //marcinobel.com/index.php/fluent-nhibernate-conventions-examples/它有这个特殊的例子:

 public class StringColumnLengthConvention    : IPropertyConvention, IPropertyConventionAcceptance {    public void Accept(IAcceptanceCriteria criteria)    {        criteria.Expect(x => x.Type == typeof(string))            .Expect(x => x.Length == 0);    }    public void Apply(IPropertyInstance instance)    {        instance.Length(100);    } } 

这看起来像你可以很容易地适应映射所有小数,就像他用字符串。