Linq到NHibernate的问题

时间:2010-09-01 13:08:36

标签: linq nhibernate linq-to-nhibernate

我目前有代码生成以下LINQ表达式(取自WhoCanHelpMe showcase项目)。它的目的是将两个表达式绑定在一起,但我不知道以下是否实际上是一个有效的表达式:

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

当评估表达式时,我得到一个Object reference not set to an instance of an object异常,其中包含以下堆栈跟踪:

  

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)      在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,IDictionary 2 enabledFilters, ICriterion criterion, Object value) at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary 2 enabledFilters)      在NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary 2 enabledFilters)      at NHibernate.Criterion.SubqueryExpression.ToSqlString(ICriteria criteria,ICriteriaQuery criteriaQuery,IDictionary 2 enabledFilters) at NHibernate.Criterion.Junction.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary 2 enabledFilters)      在NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary 2 enabledFilters) at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary 2 enabledFilters)      在NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister,ISessionFactoryImplementor factory,CriteriaImpl rootCriteria,String rootEntityName,IDictionary 2 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.CriteriaResultReader 1.List()      在NHibernate.Linq.CriteriaResultReader 1.<GetEnumerator>d__0.MoveNext() at System.Collections.Generic.List 1..ctor(IEnumerable 1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable 1来源)      at Environment.Core.Specifications.QuerySpecification 2.SatisfyingElementsFrom(IQueryable 1个候选者)在C:\ DEV \ Environment \ Environment \ app \ Environment.Core \ Specifications \ QuerySpecification.cs:第30行      at Environment.Data.NHibernate.LinqRepository 1.FindAll(ILinqSpecification 2规范)在C:\ DEV \ Environment \ Environment \ app \ Environment.Data \ NHibernate \ LinqRepository.cs:第43行    ........

更新

我尝试不使用复杂表达式运行查询:

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

仍然发生同样的错误。

2 个答案:

答案 0 :(得分:1)

您没有将linq用于对象。 NHibernate.Linq是Linq提供商。

这意味着 - 它需要知道如何您的谓词转换为有效的SQL

现在问问自己一个问题 - nhibernate支持的所有数据库怎么能知道.net类型转换?


  

抱歉,我想我需要更多的指针。更完整的代码示例会有帮助吗?

正如我所看到的 - 你正试图完成不可能的事情。我无法提供可以解决您的问题的代码示例,因为我不知道您的实际目标是什么。我只能看到你使用的是技术错误。

NHibernate.Linq能够转换为像

这样的sql表达式

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

但它无法转换为像

这样的sql表达式

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

答案 1 :(得分:0)

这是因为表达式是比较两个PostCode对象而不是比较属性。我更改了表达式,以便生成以下内容:

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