Pass expression parameter as argument to another expression

后端 未结 2 656
野趣味
野趣味 2020-11-27 06:02

I have a query which filters results:

public IEnumerable GetFilteredQuotes()
{
    return _context.Context.Quotes.Select(q => new         


        
2条回答
  •  攒了一身酷
    2020-11-27 06:31

    Implementing this your way will cause an exception thrown by ef linq-to-sql parser. Within your linq query you invokes FilterQuoteProductImagesByQuote function - this is interpreted as Invoke expression and it simply cannot be parsed to sql. Why? Generally because from SQL there is no possibility to invoke MSIL method. The only way to pass expression to query is to store it as Expression> object outside of the query and then pass it to Where method. You can't do this as outside of the query you will not have there Quote object. This implies that generally you cannot achieve what you wanted. What you possibly can achieve is to hold somewhere whole expression from Select like this:

    Expression> selectExp =
        q => new FilteredViewModel
        {
            Quote = q,
            QuoteProductImages = q.QuoteProducts.SelectMany(qp =>  qp.QuoteProductImages.AsQueryable().Where(qpi => q.User.Id == qpi.ItemOrder)))
        };
    

    And then you may pass it to select as argument:

    _context.Context.Quotes.Select(selectExp);
    

    thus making it reusable. If you would like to have reusable query:

    qpi => q.User.Id == qpi.ItemOrder
    

    Then first you would have to create different method for holding it:

    public static Expression> FilterQuoteProductImagesByQuote()
    {
        return (q,qpi) => q.User.Id == qpi.ItemOrder;
    }
    

    Application of it to your main query would be possible, however quite difficult and hard to read as it will require defining that query with use of Expression class.

提交回复
热议问题