Linq Expression EF ядро

Я пытаюсь сделать запрос к базе данных, используя дерево выражений. Мне не повезло. Я использую 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 ответ

Здесь много неправильного. Трудно точно понять, что вы пытаетесь запросить. Похоже, вы хотите что-то вроде следующего:

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; }
}
Другие вопросы по тегам