Hi,
I've created the classic IUserType to handle Money values (decimal for the
value, string for the currency). This works fine for normal queries where I
need to get the value.
However, using NH Linq (3.3.1.4000) with a Sum query, the SQL generated
includes all values, e.g.
could not execute query
[ select TOP (@p0) catalogite2_.CatalogItemId as col_0_0_, cast(count(*)
as INT) as col_1_0_, *cast(sum(itemevent0_.PriceValue,
itemevent0_.PriceCurrency) as DECIMAL(19,5)) as col_2_0_* from [ItemEvent]
itemevent0_ inner join Patron patron1_ on
itemevent0_.PatronId=patron1_.UserId inner join [User] patron1_1_ on
patron1_.UserId=patron1_1_.Id left outer join [CatalogItemDimension]
catalogite2_ on itemevent0_.CatalogItemDimensionId=catalogite2_.Id where
patron1_1_.CustomerId=@p1 group by catalogite2_.CatalogItemId order by
cast(count(*) as INT) asc ]
Name:p1 - Value:1eb48088-a7ac-42bb-bb40-72c5a0633d88 Name:p2 - Value:25
The reason is that the SUM part is being passed 2 columns by NHibernate but
SUM can only take the one value. How do I get NH to only pass the
"relevant" value, e.g. a default property?, to the query
User Type is below
[Serializable]
public class MoneyCompositeUserType : ICompositeUserType
{
public object GetPropertyValue(object component, int property)
{
// 0 =Amount
// 1 = Currency
var money = (Money)component;
if (property == 0)
{
return (decimal)money;
}
return money.Currency;
}
public void SetPropertyValue(object component, int property, object
value)
{
throw new InvalidOperationException("Money is an immutable
object. SetPropertyValue isn't supported.");
}
public new bool Equals(object x, object y)
{
if (x == y) return true;
if (x == null || y == null) return false;
return x.Equals(y);
}
public object NullSafeGet(IDataReader dr, string[] names,
ISessionImplementor session, object owner)
{
if (dr == null)
{
return null;
}
var amountColumn = names[0];
var currencyColumn = names[1];
var val = (decimal)NHibernateUtil.Decimal.NullSafeGet(dr,
amountColumn, session, owner);
var currency = NHibernateUtil.String.NullSafeGet(dr,
currencyColumn, session, owner).ToString();
var money = new Money(val, new Currency(currency));
return money;
}
public void NullSafeSet(IDbCommand cmd, object value, int index,
bool[] settable, ISessionImplementor session)
{
if (value == null)
{
return;
}
decimal amount = ((Money)value);
var currency = ((Money)value).Currency.Iso3LetterCode;
NHibernateUtil.Double.NullSafeSet(cmd, amount, index, session);
NHibernateUtil.String.NullSafeSet(cmd, currency, index + 1,
session);
}
public object DeepCopy(object value)
{
var temp = (Money)value;
return new Money((decimal)temp, temp.Currency);
}
public object Disassemble(object value, ISessionImplementor session)
{
return DeepCopy(value);
}
public object Assemble(object cached, ISessionImplementor session,
object owner)
{
return DeepCopy(cached);
}
public string[] PropertyNames
{
get { return new string[2] { "Value", "Currency" }; }
}
public IType[] PropertyTypes
{
get { return new IType[2] { NHibernateUtil.Decimal,
NHibernateUtil.String }; }
}
public Type ReturnedClass
{
get { return typeof(Money); }
}
public bool IsMutable
{
get { return false; }
}
public int GetHashCode(object x)
{
return x.GetHashCode();
}
public object Replace(object original, object target,
ISessionImplementor session, object owner)
{
return target;
}
}
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/nhusers.
For more options, visit https://groups.google.com/d/optout.