开发者

.net NHibernate Linq lambda expression chaining

开发者 https://www.devze.com 2023-02-02 02:43 出处:网络
I\'m trying to create a method which create the where predicate to use later on a linq where method (Linq2NHibernate).

I'm trying to create a method which create the where predicate to use later on a linq where method (Linq2NHibernate). what I have here is a method that perform the creation of an expression that will be used in a query Linq. Let's see some code

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;            
}

The expression will be more complex than a simple "always true", but for the problem I have I got the same behaviour. The .And you see is an extension method (I found here on SO for real)

 internal static class PredicateExtensions
{
    public static Expression<Func<T, bool>> And<T>(this Expression<Func开发者_如何学C<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);
    }
}

Now I have a Business Logic class with a method that collect the Expression created and pass it to the DAL manager. That method simply calls

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

As you can see I retrieve another expression from the Securitymanager (in case you doubt, the problem occour even if I avoid to chain toghether the 2 expression) and then call

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

This is where everything is put toghether to make the query

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();
      }  
   }
}

So, when I call the method that perform the query, it gaves e back an error in the .ToList() call you see in the last line. The error is Object reference not set to an instance of an object. And it occurs in NHibernate.Linq. The problem seems to be related to the And extension method, since it works if I make a simple expression, without any chaining. What's wrong? If I simply compile the expression befor passing it to the genericDalManager.getFilteredList method, everything works, but it will not evaluate the expression as a query on the database (obviously the "always true" expression won't generate any interesting where clause, but I need this to work in order to do some more complex filter). The strange thing is that if I won't chain the two "always true" expression in the method getUserFiltreExpression, but I return only the first one, everything works fine. Even if after the same expression will be chained with the result of BL.SecurityManager().getFilterExpression(user) calling. And by the way, for testing this issue, this last call return another "always true" expression.

Anyone help please... I'm getting mad!


I guess the problem is that you And with the result of the expression (after invoke) and not with the expression itself. That expression can probably not be parsed. You might also have to you AndAlso (logical and) insead of And (bitwise and) and maybe rebind the parameters

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号