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.

Reply via email to