I'm trying to execute a query by settings its parameters via the SetProperties() method on IQuery. I am having 2 separate but related issues. But first, my code...
The HQL:
FROM CarrierService cs
WHERE cs.Carrier = :Carrier
AND cs.Service in (:Services)
Notice the first parameter is a mapped entity object and the second parameter is a collection of mapped entities. This query works fine when using query.SetParameter and query.SetParameterList. The issue arises when trying to introduce a criteria object...
public class CarrierServiceQueryCriteria : QueryCriteria<ICarrierService>
{
private ICarrier carrier;
private IShippingService[] services;
public ICarrier Carrier
{
get { return carrier; }
set { carrier = value; }
}
public IShippingService[] Services
{
get { return services; }
set { services = value; }
}
}
When I try to run the query by setting the parameters via the SetProperties method (and passing in a properly constructed instance) I get the error:
NHibernate.QueryException: Not all named parameters have been set: [Carrier] [
FROM CarrierService cs
WHERE cs.Carrier = :Carrier
AND cs.Service in (:Services)
]
Apparent problem: It appears the logic behind SetProperties() doesn't handle the domain objects' interfaces. Using the class is not an option since we are using interfaces for lazy loading and such.
So then I tried changing my query/object to just pass the integer key values...
The new HQL:
FROM CarrierService cs
WHERE cs.Carrier.Id = :CarrierId
AND cs.Service.Id in (:ServiceIds)
The new class:
public class CarrierServiceQueryCriteria : QueryCriteria<ICarrierService>
{
private int carrierId;
private int[] serviceIds;
public int CarrierId
{
get { return carrierId; }
set { carrierId = value; }
}
public int[] ServiceIds
{
get { return serviceIds; }
set { serviceIds = value; }
}
}
The query no longer throws an exception but does not return results. Turning on show_sql reveals the problem:
NHibernate: select ... from CarrierService carrierser0_ where (carrierser0_.Carrier=@p0 )AND(carrierser0_.Service in(@p1)); @p0 = '149', @p1 = 'System.Byte[]'
Notice how @p1 is being set to the type name. Apparent problem: The query logic didn't pick up on the fact that I wanted a parameter list.
For comparison, here is the SQL generated when I run the same HQL by setting parameters via SetParameter and SetParameterList:
NHibernate: select ... from CarrierService carrierser0_ where (carrierser0_.Carrier=@p0 )AND(carrierser0_.Service in(@p1 , @p2 , @p3 , @p4 , @p5 , @p6 , @p7 , @p8 , @p9 , @p10 , @p11 , @p12 , @p13 , @p14 , @p15)); @p0 = '149', @p1 = '1', @p2 = '8', @p3 = '17', @p4 = '12', @p5 = '3', @p6 = '15', @p7 = '18', @p8 = '4', @p9 = '10', @p10 = '5', @p11 = '16', @p12 = '11', @p13 = '19', @p14 = '20', @p15 = '7'
Am I doing something wrong or are these 2 things limitations of the SetProperties method logic?
I checked over the documentation and searched the net and these forums and could not find any relevant discussion. I tried looking at the NH source code but could not make sense of what I was looking at.
Is this something planned to be added to the code base? Does it need a volunteer? Can someone point me to the right place(s) where this would need to get implemented? I need this functionality and am willing to implement it with some assistance and knowing that it would eventually get integrated into the official code base. Please advise.
|