views:

100

answers:

2

I currently have code which produces the following LINQ expression (taken from the WhoCanHelpMe showcase project). Its purpose is to bind together two expressions but I don't know if the following is actually a valid expression:

.Where(p => (p.PostCodes
      .Any(pc =>(pc = value(PatchByPostCodeSpecification).postCode)) &&
         Invoke(p => p.Teams
                    .Any(t => (Convert(t.TeamType) = 
                     Convert(value(PatchByBookingTypeSpecification).bookingType))), 
         p
       )
      ));

When the expression is evaluated I get an Object reference not set to an instance of an object exception with the following stack trace:

at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetEntityName(ICriteria subcriteria, String propertyName) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(String propertyName, ICriteria subcriteria) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName) at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingPropertyName(ICriteriaQuery criteriaQuery, ICriteria criteria, String propertyName, Object value, ICriterion critertion) at NHibernate.Criterion.CriterionUtil.GetColumnNamesForSimpleExpression(String propertyName, IProjection projection, ICriteriaQuery criteriaQuery, ICriteria criteria, IDictionary2 enabledFilters, ICriterion criterion, Object value) at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary2 enabledFilters) at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary2 enabledFilters) at NHibernate.Criterion.Junction.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary2 enabledFilters) at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) at NHibernate.Impl.CriteriaImpl.List(IList results) at NHibernate.Impl.CriteriaImpl.List() at NHibernate.Linq.CriteriaResultReader1.List() at NHibernate.Linq.CriteriaResultReader1.<GetEnumerator>d__0.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Environment.Core.Specifications.QuerySpecification2.SatisfyingElementsFrom(IQueryable1 candidates) in C:\DEV\Environment\Environment\app\Environment.Core\Specifications\QuerySpecification.cs:line 30 at Environment.Data.NHibernate.LinqRepository1.FindAll(ILinqSpecification2 specification) in C:\DEV\Environment\Environment\app\Environment.Data\NHibernate\LinqRepository.cs:line 43 ........

UPDATE

I've tried running the query without using a complex expression:

.Where(p => (p.PostCodes
      .Any(pc =>
          (pc = value(PatchByPostCodeSpecification).postCode)
          )));

The same error still occurred.

+1  A: 

You are not using linq to objects. NHibernate.Linq is a Linq provider.

That means - it needs to know how to translate Your predicate into valid SQL.

Now ask Yourself a question - how on earth all databases nhibernate supports could ever know about .net type conversion?


Sorry I think I'll need a bit more of a pointer than that. Would a more complete code sample help?

As I see it - You are trying to accomplish impossible. I can't provide code sample that would solve Your problem cause I got no ideas what Your actual aim is. all I can see is that You are using technology wrong.

NHibernate.Linq is able to translate into sql expressions like

orders.Any(o=>o.Customers.Any(c=>c.IsDead)).Where(o=>o.Price==10)

But it's not able to translate into sql expressions like

orders.Where(o=>{Console.WriteLine("foo"); MsgBox("bar"); return false;})

Arnis L.
Sorry I think I'll need a bit more of a pointer than that. Would a more complete code sample help?
David Neale
Thanks for the help - you pointed me in the right direction.
David Neale
A: 

This was caused because the expression was comparing two PostCode objects rather than comparing on properties. I changed the expression so that the following is produced:

.Where(p => (p.PostCodes
  .Any(pc =>
      (pc.Name = value(PatchByPostCodeSpecification).postCode.Name)
      )));
David Neale
I'm still confused about that `value(...)` function. What is that? But yeah - it's usually with linq providers like that. If it doesn't work - try to express Yourself simpler and it might.
Arnis L.