The parameter '***' was not bound in the specified LINQ to Entities query expression
Asked Answered
P

1

6

I am doing a common query in my project. I use Expression to build my query tree, the code list below:

 public IList<Book> GetBooksFields(string fieldName, string fieldValue)
    {
        ParameterExpression paramLeft = Expression.Parameter(typeof(string), "m." + fieldName);
        ParameterExpression paramRight = Expression.Parameter(typeof(string), "\"" + fieldValue + "\"");

        ParameterExpression binaryLeft = Expression.Parameter(typeof(Book),"m");
        BinaryExpression binaryExpr = Expression.Equal(paramLeft, paramRight);

        var expr = Expression.Lambda<Func<Book, bool>>(binaryExpr, binaryLeft);

        return bookRepository.GetMany(expr).ToList();

    }

But when I invoke my GetBooksFields method, it will throw me an exception as below: enter image description here

I debugged the expr variable and got the correct expression: {m => (m.Name == "sdf")}, it was what I want, But I don't know why I got the error,thx.

Password answered 11/4, 2014 at 4:29 Comment(0)
U
7

You can't "trick" LINQ into interpreting parameters as member-expressions by throwing in dots into variable names.

You'll have to construct the expression-tree correctly, as below (EDIT: changed field to property as per your comment):

public IList<Book> GetBooksFields(string propertyName, string propertyValue)
{
     var parameter = Expression.Parameter(typeof(Book), "book");

     var left = Expression.Property(parameter, propertyName);   

     var convertedValue = Convert.ChangeType
                          ( 
                              propertyValue, 
                              typeof(Book).GetProperty(propertyName).PropertyType
                          );

     var right = Expression.Constant(convertedValue);

     var binaryExpr = Expression.Equal(left, right);        
     var expr = Expression.Lambda<Func<Book, bool>>(binaryExpr, parameter);     

     return bookRepository.GetMany(expr).ToList();          
}
Untenable answered 11/4, 2014 at 4:41 Comment(8)
thanks. But I tried your approach and got error at row : Expression.Field(parameter, fieldName), the exception is : Didn't define field "Name" for type "TinyFrame.Data.DomainModel.Book". Any ideas? I can see in my BookDomainmodel, there are "Name" field.Password
Is it a field or a property? Show us your Book class.Untenable
sry for my mistake, it's a property: public int ID { get; set; } public string Name { get; set; } public string Author { get; set; } public string Publishment { get; set; } public int BookTypeID { get; set; } public int BookPlaceID { get; set; } public virtual BookType BookType { get; set; } public virtual BookPlace BookPlace { get; set; }Password
I modified all the field to property , and now it works fine.Password
@Untenable You also could've used Expression.PropertyOrField().Hagride
@svick: I could have, yes. But note I'm also getting the member through typeof(Book).GetProperty(propertyName).PropertyType, which is harder to generalize across fields / properties. Although I suppose left.ExpressionType would have worked and been easier...Untenable
@Untenable If i want to do query the property in nested entities, What should I do now? ie, I want to query the property "Position" in BookPlace entity, which exists in Book entity?Password
@Untenable I used the System.Linq.Dynamic lib , all my questions are now solved, thx for your help .Password

© 2022 - 2024 — McMap. All rights reserved.