Is there any programmatic approach to inject nhibernate UserTypes?
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)
开发者_C百科 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
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
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>());
}
精彩评论