Как дать имя свойства в строке в лямбда-выражении? - PullRequest
0 голосов
/ 09 октября 2018

Я хочу написать запрос в ядре .net, используя ef.Теперь проблема в том, что я получаю имя свойства в параметре и хочу наложить условие на это свойство, например

  public IQueryable<MyModel> Generate(string property, IQueryable<MyModel> query)
  {
    query = query.Where(a => a.property.ToLower() != null);
  }

MyModel:

public string Property1 { get; set; }
public string Property2 { get; set; }
public string Property3 { get; set; }

Вызов метода:

var query = Generate(MyModel.Property2, query);

Я знаю, что это возможно с помощью отражения, но это оказывает некоторое влияние на производительность.Так есть ли лучший подход?

Ответы [ 3 ]

0 голосов
/ 09 октября 2018

Вы можете сделать это так:

public IQueryable<TModel> Generate<TModel, TProperty>(Func<TModel, TProperty> propertyFunc, IQueryable<TModel> query)
{
    return query.Where(a => propertyFunc(a) != null);
}

Это будет более гибкое решение, чем Дмитрий.

0 голосов
/ 09 октября 2018

РЕДАКТИРОВАТЬ после уточнения вопроса:

Вы можете реализовать универсальный метод расширения для IQueryable, когда предложение динамически создается:

public static class QueryExtensions
{
    public static IQueryable<TModel> WhereNotNull<TModel>(this IQueryable<TModel> query, string propertyName)
    {
        var parameter = Expression.Parameter(typeof(TModel), "x");
        var body = Expression.PropertyOrField(parameter, propertyName);
        var comparison = Expression.NotEqual(body, Expression.Constant(null, typeof(object)));
        var lambda = Expression.Lambda<Func<TModel, bool>>(comparison, parameter);
        return query.Where(lambda);
    }
}

Вызовите его следующим образом:

query = query.WhereNotNull(nameof(MyModel.Property1));

или

query = query.WhereNotNull("Property1");

РЕДАКТИРОВАТЬ после запроса проверки на наличие пустых или пробельных символов для строк:

Пример вызова string.IsNullOrWhiteSpace() для свойств строки:

public static IQueryable<TModel> WhereNotNull<TModel>(this IQueryable<TModel> query, string propertyName)
{
    var parameter = Expression.Parameter(typeof(TModel), "x");
    var body = Expression.PropertyOrField(parameter, propertyName);
    Expression<Func<TModel, bool>> lambda = null;
    if (body.Type == typeof(string))
    {
        var methodCall = Expression.Call(typeof(string), nameof(string.IsNullOrWhiteSpace), null, body);
        var nullOrWhiteSpaceComparison = Expression.Not(methodCall);
        lambda = Expression.Lambda<Func<TModel, bool>>(nullOrWhiteSpaceComparison, parameter);
    }
    else
    {
        var nullComparison = Expression.NotEqual(body, Expression.Constant(null, typeof(object)));
        lambda = Expression.Lambda<Func<TModel, bool>>(nullComparison, parameter);
    }
    return query.Where(lambda);
    }

Если вы (в каком-то другом контексте) хотите объединить несколько выражений, вы можете использовать Expression.And(Expression left, Expression right) или Expression.Or(Expression left, Expression right).Передайте одинарное / двоичное выражение в качестве параметров слева и справа.

0 голосов
/ 09 октября 2018

Можете ли вы использовать Func<MyModel, string> в качестве параметра?

public IQueryable<MyModel> Generate(Func<MyModel, string> propertySelector, IQueryable<MyModel> query)
{
   query = query.Where(a => propertySelctor(a).ToLower() != null);
}

И использовать как:

var query = Generate(m => m.Property2, query);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...