Linq Expression EF核心

时间:2018-03-03 22:33:19

标签: c# linq linq-to-sql linq-expressions

我正在尝试使用表达式树查询数据库。我没有运气。我正在使用EF Core。

我正在

Expression of type 'System.String' 
cannot be used for parameter of type 'System.Linq.IQueryable`1[TestExpression.Model.Status]' 
of method 'Boolean Contains[Status](System.Linq.IQueryable`1[TestExpression.Model.Status], TestExpression.Model.Status)

代码

    public static void SearchByColumn(string term)
    {
        TestModel testModel = new TestModel();
        IQueryable<Status> sourceQueryable = testModel.Status;

        IQueryable<string> selectQueryable = sourceQueryable.Select(product => product.Name);
        IQueryProvider selectQueryProvider = selectQueryable.Provider; // DbQueryProvider.

        ConstantExpression constantExpression = MethodCallExpression.Constant(term);

        Func<IQueryable<Status>, Status, bool> contains = Queryable.Contains;
        ParameterExpression statusParameterExpression = Expression.Parameter(typeof(Status), "status");

        MethodCallExpression methodCallExpression = Expression.Call(
            method: contains.Method,
            arg0: Expression.Property(statusParameterExpression, nameof(Status.Name)), 
            arg1: constantExpression);

        var someval = selectQueryProvider.Execute<Status>(methodCallExpression); // Execute query.
    }

1 个答案:

答案 0 :(得分:0)

这里有很多错误,很难确切地知道你要查询什么。您似乎想要以下内容:

from testModel.Status s
where s.name.Contains(term)
select s

您获得例外是因为您尝试使用Queryable.Contains而不是string.Contains

以下是您可以采用的方法(使用LINQPad测试)

void Main() {
    // test setup
    var term = "test";

    var source = new [] {
        new Status { Name = "some test" },
        new Status { Name = "test other" },
        new Status { Name = "other" }
    }.AsQueryable();

    // build expression 
    // s => s.Name.Contains("{term}")
    var paramExpr    = Expression.Parameter(typeof(Status), "s");
    var nameExpr     = Expression.Property(paramExpr, nameof(Status.Name));
    var termExpr     = Expression.Constant(term);
    var containsExpr = Expression.Call(nameExpr, nameof(string.Contains), new Type[] { }, termExpr);
    var lambda       = Expression.Lambda<Func<Status, bool>>(containsExpr, paramExpr);

    source.Where(lambda).Dump(); 
}

public class Status {
    public string Name { get; set; }
}