【问题标题】:.net NHibernate Linq lambda expression chaining.net NHibernate Linq lambda 表达式链接
【发布时间】:2011-01-04 11:06:26
【问题描述】:

我正在尝试创建一个方法来创建 where 谓词,以便稍后在 linq where 方法 (Linq2NHibernate) 上使用。 我这里有一个方法,它执行创建将在查询 Linq 中使用的表达式。 让我们看一些代码

private Expression<Func<Model.FattureEmesse, bool>> getUserFilterExpression(FattureFilter filterStructure)
{
  Expression<Func<Model.FattureEmesse, bool>> dataDocumentoFilter = f =>
     true;

  Expression<Func<Model.FattureEmesse, bool>> dataFineValiditaFilter = f =>
     true;

  var userFilterExpression = dataDocumentoFilter
     .And(dataFineValiditaFilter)
     .And(dataImportazioneFilter);

  return userFilterExpression;            
}

该表达式将比简单的“始终正确”更复杂,但对于我遇到的问题,我得到了相同的行为。 .And 你看到的是一种扩展方法(我在 SO 上找到了真实的)

 internal static class PredicateExtensions
{
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) where T : Model.DomainModelObject
    {
        InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());

        return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
    }
}

现在我有一个业务逻辑类,其中包含一个收集创建的表达式并将其传递给 DAL 管理器的方法。 该方法只是调用

var userFilterExpression = getUserFilterExpression(filterStructure);
var securityFilterExpression = new BL.SecurityManager().getFilterExpression<Model.FattureEmesse>(user);
var totalFilterExpression = userFilterExpression.And(securityFilterExpression);

如您所见,我从 Securitymanager 中检索了另一个表达式(如果您怀疑,即使我避免将 2 表达式链接在一起,也会出现问题) 然后调用

var filteredFatture = new GenericDalManager().getFilteredList<Model.FattureEmesse>(maximumRows, startRowIndex, totalFilterExpression);

这是将所有内容放在一起进行查询的地方

public class GenericDalManager
{
   internal IList<T> getFilteredList<T>(int maximumRows, int startRowIndex, Expression<Func<T, bool>> expressionResult) where T : Model.DomainModelObject
   {   
      using (var session = PersistenceManager.Istance.GetSession())
      {
         var items = (from o in session.Linq<T>()
                      orderby o.Id
                      select o);

         var filteredItems = items.Where(expressionResult)
                                  .Skip(startRowIndex)
                                  .Take(maximumRows);                    

         return filteredItems.ToList();
      }  
   }
}

所以,当我调用执行查询的方法时,它会在最后一行看到的 .ToList() 调用中返回错误。 错误是 你调用的对象是空的。 它发生在 NHibernate.Linq 中。 这个问题似乎与 And 扩展方法有关,因为如果我做一个简单的表达式,没有任何链接,它就可以工作。 怎么了? 如果我在将表达式传递给 genericDalManager.getFilteredList 方法之前简单地编译表达式,一切正常,但它不会将表达式评估为数据库上的查询(显然“始终为真”表达式不会生成任何有趣的 where 子句,但是我需要这个工作才能做一些更复杂的过滤器)。 奇怪的是,如果我不在 getUserFiltreExpression 方法中链接两个“始终为真”的表达式,但我只返回第一个,一切正常。即使在相同的表达式之后将与 BL.SecurityManager().getFilterExpression(user) 调用的结果链接。 顺便说一句,为了测试这个问题,最后一次调用返回另一个“始终为真”的表达式。

请大家帮忙...我快生气了!

【问题讨论】:

    标签: nhibernate .net-4.0 lambda expression-trees linq-to-nhibernate


    【解决方案1】:

    我猜问题是你和表达式的结果(在调用之后)而不是表达式本身。该表达式可能无法解析。您可能还需要 AndAlso(逻辑与)而不是 And(按位与),并且可能需要重新绑定参数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多