1

I have a repository where several methods are using the same piece of logic within the predicate.

public IList<Loan> GetLoansByCommitmentID(int commitmentID)
{

    var query = this.context.Loans.Where(l => l.CommitmentLoan != null &&
                                         l.CommitmentLoan.CommitmentID == commitmentID && 
                                         (l.LoanStatusTypes == null || (l.LoanStatusTypes.Description != "Invalid")));

    return query.ToList();
}

In the code above, it's the last parenthesized subexpression:

(l.loanStatusTypes == null || (l.LoanStatusTypes.Description != "Invalid"))

I'd like to move this piece into a private method of the repository so that it takes a Loan, in this case, and evaluates to a boolean. If I move this logic into a method, however, EF does not understand how to evaluate the method call. So after thinking on it a bit, I decided perhaps the right way to do this would be for the private repository method to take a Loan as a parameter then return an Expression to be used in the calling lambda expression, kind of like an Expression factory method i.e.:

public Expression IsLoanInvalid(Loan l);

Does anyone know if this will overcome the inability of EF to understand the method call or should I instead be creating a custom ExpressionVisitor or is there another solution I should be trying?

Also, if the above proposed solution is possible and I go this route, how can I build an expression tree so that it uses the parameter passed in? I've successfully implemented the a method that builds the expression but have been unsuccessful thus far in passing the Loan parameter to the Expression I am building to be returned to the calling code. Thank you in advance.

4

1 回答 1

1

You could create a variable to hold that piece of your where predicate.

public Expression<Func<Loan, bool>> LoanStatus = loan => loan.LoanStatusTypes == null || loan.LoanStatusTypes.Description != "Invalid";

And then add a second where off your IQueriable

public IList<Loan> GetLoansByCommitmentID(int commitmentID)
{    
    var query = this.context.Loans
         .Where(l => l.CommitmentLoan != null && l.CommitmentLoan.CommitmentID == commitmentID)
         .Where(LoanStatus);

    return query.ToList();
}
于 2012-12-14T19:35:51.537 回答