是否有任何编程方法来注入 nhibernate UserTypes?

发布于 2024-11-27 13:06:35 字数 3117 浏览 0 评论 0原文

我有一个使用 Nhibernate 和 Microsoft Sql Server 开发的应用程序,但现在我正尝试将其迁移到 SQLite。我发现 SQLite 存在问题,它没有为我提供适当的定点数格式和准确的货币值算术。因此,为了解决这个问题,我通过编写自定义 IResultTransformer 和 UserType (FixedPointDecimalUserType) 来模拟定点行为。另外,我想在应用程序之间共享映射。

我有一个扩展可以将我的 UserType 注入属性和组件映射中,其中类型是十进制

<property name="Quantity" not-null="true" type="Decimal(8,3)"/>

我的扩展是这样的:

public static class NHExtensions
    {

        public static NHibernate.Cfg.Configuration AdaptToSQLite(this NHibernate.Cfg.Configuration configuration)
        {
            if (configuration.ClassMappings.Count == 0)
                throw new InvalidOperationException("Es necesario añadir el assembly al configuration antes de llamar a este método");

            if (configuration.Properties[NHibernate.Cfg.Environment.Dialect].IsIn(typeof(SQLiteDialect).FullName, typeof(SQLiteDialect).AssemblyQualifiedName))
            {
                foreach (var mapping in configuration.ClassMappings)
                    foreach (var property in mapping.PropertyIterator)
                        AdaptProperty(property);

                foreach (var mapping in configuration.CollectionMappings)
                    How to get inject FixedPointUserType?

            }
            return configuration;
        }

        public static void AdaptProperty(Property property)
        {
            if (property.IsComposite)
            {
                var component = property.Value as Component;
                component.PropertyIterator.Each(AdaptProperty);
            }

            if (property.Type.GetType() == typeof(DecimalType))
            {
                var simpleValue = property.Value as SimpleValue;
                if (simpleValue != null)        
                    simpleValue.TypeName = typeof(FixedPointDecimalUserType).AssemblyQualifiedName;
            }
        }
    }

但是当我找到 NHibernate.Mapping.List<>我不知道如何注入我的 UserType,例如 SoldProduct。

<list name="Addins" table="TicketLineAddin" fetch="join">
    <key column="TicketLineId" ..../>
    <index column="AddinIndex"/>
    <composite-element class="Domain.Catalogue.SoldProduct, Domain">
        <property name="ProductId" not-null="true"/>
        <property name="ProductName" not-null="true" length="120"/>
        <property name="Price" not-null="true" type="Decimal(12,3)"/>
        <property name="VatId" column="VatId"  not-null="true"/>
        <property name="VatRate" column="VatRate"  not-null="true" type="Decimal(12,3)"/>
        <property name="PreparationType" not-null="true" type="Common.Ordering.PreparationType, Common"/>
        <property name="PriceListId" not-null="true"/>
        <property name="PrintMode" not-null="true"/>
    </composite-element>
</list>

另一种选择可能是 SQL Server 和 SQLite 应用程序的不同自定义 UserType 实现,并替换我的 .hbm 文件中的所有十进制类型,

<property name="Quantity" not-null="true" type="FixedPointUserType"/>

但是,是否有任何编程方法可以解决此问题?

提前致谢

I have an application developed with Nhibernate and Microsoft Sql Server, but now I´m trying to migrate it to SQLite. I have found a problem with SQLite, it doesn´t give me an appropriate fixed point number format and accurate arithmetic for money values. So, to resolve this problem I simulate fixed point behaviour writing custom IResultTransformer and UserType (FixedPointDecimalUserType). Also, I want to share mappings between applications.

I have an extension to inject my UserType in properties and components mappings where type is decimal

<property name="Quantity" not-null="true" type="Decimal(8,3)"/>

My extension is like this:

public static class NHExtensions
    {

        public static NHibernate.Cfg.Configuration AdaptToSQLite(this NHibernate.Cfg.Configuration configuration)
        {
            if (configuration.ClassMappings.Count == 0)
                throw new InvalidOperationException("Es necesario añadir el assembly al configuration antes de llamar a este método");

            if (configuration.Properties[NHibernate.Cfg.Environment.Dialect].IsIn(typeof(SQLiteDialect).FullName, typeof(SQLiteDialect).AssemblyQualifiedName))
            {
                foreach (var mapping in configuration.ClassMappings)
                    foreach (var property in mapping.PropertyIterator)
                        AdaptProperty(property);

                foreach (var mapping in configuration.CollectionMappings)
                    How to get inject FixedPointUserType?

            }
            return configuration;
        }

        public static void AdaptProperty(Property property)
        {
            if (property.IsComposite)
            {
                var component = property.Value as Component;
                component.PropertyIterator.Each(AdaptProperty);
            }

            if (property.Type.GetType() == typeof(DecimalType))
            {
                var simpleValue = property.Value as SimpleValue;
                if (simpleValue != null)        
                    simpleValue.TypeName = typeof(FixedPointDecimalUserType).AssemblyQualifiedName;
            }
        }
    }

but when I find a NHibernate.Mapping.List<> I don´t know how to inject my UserType, for example for SoldProduct.

<list name="Addins" table="TicketLineAddin" fetch="join">
    <key column="TicketLineId" ..../>
    <index column="AddinIndex"/>
    <composite-element class="Domain.Catalogue.SoldProduct, Domain">
        <property name="ProductId" not-null="true"/>
        <property name="ProductName" not-null="true" length="120"/>
        <property name="Price" not-null="true" type="Decimal(12,3)"/>
        <property name="VatId" column="VatId"  not-null="true"/>
        <property name="VatRate" column="VatRate"  not-null="true" type="Decimal(12,3)"/>
        <property name="PreparationType" not-null="true" type="Common.Ordering.PreparationType, Common"/>
        <property name="PriceListId" not-null="true"/>
        <property name="PrintMode" not-null="true"/>
    </composite-element>
</list>

An alternative could be a different custom UserType implementation for SQL Server and SQLite application and replace all decimal types in my .hbm files

<property name="Quantity" not-null="true" type="FixedPointUserType"/>

but, is there any programmatic approach to resolve this?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雪花飘飘的天空 2024-12-04 13:06:35
foreach (var mapping in config.CollectionMappings)
{
    if (mapping.Element.Type.IsComponentType)
    {
        var subtypes = ((ComponentType)mapping.Element.Type).Subtypes;
        for (int i =0; i < subtypes.Length; i++)
        {
            if (subtypes[i].GetType() == typeof(DecimalType))
            {
                subtypes[i] = new FixedPointDecimalUserType();
            }
        }
    }
}

但无法测试它

foreach (var mapping in config.CollectionMappings)
{
    if (mapping.Element.Type.IsComponentType)
    {
        var subtypes = ((ComponentType)mapping.Element.Type).Subtypes;
        for (int i =0; i < subtypes.Length; i++)
        {
            if (subtypes[i].GetType() == typeof(DecimalType))
            {
                subtypes[i] = new FixedPointDecimalUserType();
            }
        }
    }
}

cant test it though

天邊彩虹 2024-12-04 13:06:35

使用此代码可以正常工作,谢谢

configuration.BuildMappings();

    ...
foreach(...)
    if (mapping.Element.Type.IsComponentType)
    {
        var subtypes = ((ComponentType)elementType).Subtypes;
        for (var i = 0; i < subtypes.Length; i++)
            if (subtypes[i].GetType() == typeof(DecimalType))
                subtypes[i] = new CustomType(typeof(FixedPointDecimalUserType), new Dictionary<string, string>());

    }

With this code works fine, thanks

configuration.BuildMappings();

    ...
foreach(...)
    if (mapping.Element.Type.IsComponentType)
    {
        var subtypes = ((ComponentType)elementType).Subtypes;
        for (var i = 0; i < subtypes.Length; i++)
            if (subtypes[i].GetType() == typeof(DecimalType))
                subtypes[i] = new CustomType(typeof(FixedPointDecimalUserType), new Dictionary<string, string>());

    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文