简体   繁体   English

LINQ to Entities-无法识别的方法

[英]LINQ to Entities - Method not recognized

I'm facing a problem with executing a query against a Queryable dataset. 我在对Queryable数据集执行查询时遇到问题。 The original call looks like this: 原始呼叫如下所示:

books = books.Where(b => (GetPropertyValue(b, filter.CategoryProperties.DbName) == null ? 0 : Convert.ToInt32(GetPropertyValue(b, filter.CategoryProperties.DbName))) < Convert.ToInt32(filter.Value));

This gets me the Method not recognized error. 这使我无法识别方法错误。 This of course is expected due to the call to GetPropertyValue. 当然,这是由于调用GetPropertyValue而引起的。 I then read that I should build the expression tree myself. 然后,我读到我应该自己构建表达式树。 That result in the following code: 结果是以下代码:

public IQueryable<Books> GetExpression(IQueryable<Books> books, BookCategoryMapping filter)
    {
        var booksExpression = Expression.Parameter(typeof(Books), "b");
        var methodInfo = this.GetType().GetMethod("GetPropertyValue");
        var value = Expression.Call(methodInfo, booksExpression, Expression.Constant(filter.CategoryProperties.DbName));
        var left = Expression.Constant(value);
        var right = Expression.Constant(filter.Value);
        var expression = Expression.Equal(left, right);
        var whereExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { books.ElementType }, books.Expression, Expression.Lambda<Func<Books, bool>>(expression, new ParameterExpression[] { booksExpression }));
        return books.Provider.CreateQuery<Books>(whereExpression);
    }

Only problem being, that I get the same error. 唯一的问题是,我得到了相同的错误。 It seems like the following line only produces an expression and not the value of said expression. 似乎以下行仅生成一个表达式,而不生成所述表达式的值。

var value = Expression.Call(methodInfo, booksExpression, Expression.Constant(filter.CategoryProperties.DbName));

Any help producing the correct expression tree would be greatly appreciated :-) 产生正确表达树的任何帮助将不胜感激:-)

EDIT: Here's the GetPropertyValue method: 编辑:这是GetPropertyValue方法:

public static object GetPropertyValue(object obj, string name)
    {
        try
        {
            return obj.GetType().GetProperty(name)?.GetValue(obj, null);
        }
        catch (Exception ex)
        {
            LogManager.Log(LogLevel.Error, null, ex);
        }

        return obj;
    }

The method below generates an Expression<Func<Book, bool>> which determines whether a given property of a Book is less than a given (constant) value. 下面的方法生成一个Expression<Func<Book, bool>> ,该Expression<Func<Book, bool>>确定Book的给定属性是否小于给定(常数)值。 The error-checking code you currently have in GetPropertyValue can probably be replaced by catching the ArgumentException which will be thrown when you try to create an expression for a nonexistent property. 您当前在GetPropertyValue具有的错误检查代码可能可以通过捕获ArgumentException来替换,当您尝试为不存在的属性创建表达式时将抛出该异常。

Note that I have assumed that the property you're accessing is genuinely numeric, and that your call to Convert.ToInt32 was only necessary because your GetPropertyValue method returns an object . 请注意,我假设您正在访问的属性是真正的数字,并且仅由于您的GetPropertyValue方法返回一个object ,才需要对Convert.ToInt32进行调用。

Expression<Func<Book, bool>> GenerateLessThanExpression(string propertyName, int value)
{
    var parameter = Expression.Parameter(typeof (Book));
    var property = Expression.Property(parameter, propertyName);
    var comparison = Expression.LessThan(property, Expression.Constant(value));

    return Expression.Lambda<Func<Book, bool>>(comparison, parameter);
}

Here's a sample usage to return only very short books: 这是仅返回非常短的书籍的示例用法:

var filter = GenerateLessThanExpression("Pages", 5);
var filtered = books.Where(filter);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM