Как применить дерево выражений к объекту с нулевыми параметрами - PullRequest
0 голосов
/ 29 марта 2019

У меня есть этот объект

public class Ledger
{
   public string fund {get;set;}
   public string location {get;set;}
   public string costCenter {get;set;}
   public string objects {get;set;}
}

Я использую этот параметр фильтра, который означает, что каждое из этих значений может быть нулевым или может быть заполнено. В SQL запрос будет выглядеть следующим образом:

SELECT FROM GlAccts WHERE fund = "10" AND location = "1" AND objects = "45"
SELECT FROM GlAccts WHERE objects = "45"
SELECT FROM GlAccts WHERE location = "1" AND objects = "45"

Я пытаюсь преобразовать это в linq, я наткнулся на дерево выражений, которое звучит странно, но у меня есть несколько проблем,

  1. Как я могу вернуть список GlAccts с деревом выражений
  2. Как объединить выражение с AND, если у меня есть нулевое выражение.

Это то, что у меня сейчас есть.

// filtersObject, is my object which would contains fund,location,costCenter,object, just to note it is currently in a foreach (var filtersObjects) since I plan to have multiple filter objects but i am not worry about this section.
// my active list right now is List<glUserAccess> but I dont know where to apply this


            ParameterExpression pe = Expression.Parameter(typeof(GlAccts), "glAccts");

            Expression e1 = null;
            Expression e2 = null;
            Expression e3 = null;
            Expression e4 = null;

            // Fund EQ ""
            if (!string.IsNullOrEmpty(filtersObject.fund)) {
                Expression left = Expression.Property(pe, typeof(string).GetProperty("fund")); ;
                Expression right = Expression.Constant(filtersObject.fund, typeof(string));
                e1 = Expression.Equal(left, right);
            }

            // Location EQ ""
            if (!string.IsNullOrEmpty(filtersObject.location)) {
                Expression left = Expression.Property(pe, typeof(string).GetProperty("location")); ;
                Expression right = Expression.Constant(filtersObject.location, typeof(string));
                e2 = Expression.Equal(left, right);
            }

            // Cost Center EQ ""
            if (!string.IsNullOrEmpty(filtersObject.costCenter)) {
                Expression left = Expression.Property(pe, typeof(string).GetProperty("costCenter")); ;
                Expression right = Expression.Constant(filtersObject.costCenter, typeof(string));
                e3 = Expression.Equal(left, right);
            }

            // Objects EQ ""
            if (!string.IsNullOrEmpty(filtersObject.objects)) {
                Expression left = Expression.Property(pe, typeof(string).GetProperty("objects")); ;
                Expression right = Expression.Constant(filtersObject.objects, typeof(string));
                e4 = Expression.Equal(left, right);
            }

            var e1e2 = Expression.AndAlso(e1,e2);
            var e1e2e3 = Expression.AndAlso(e1e2, e3);
            var e1e2e3e4 = Expression.AndAlso(e1e2e3, e4);

            var ExpressionTree = Expression.Lambda<Func<GlAccts, bool>>(e1e2e3e4, new[] { pe });

1 Ответ

1 голос
/ 29 марта 2019

Вы можете объединить ваши подвыражения с AndAlso. Следующий код использует отражение, чтобы получить все свойства из Ledger и создать динамическое лямбда-выражение:

public static Expression<Func<T, bool>> CreateExpression<T>(Ledger ledger)
{
    var parameter = Expression.Parameter(typeof(T), "x");

    Expression body = null;
    foreach (var property in ledger.GetType().GetProperties())
    {
        var value = property.GetValue(ledger);
        if (value == null)
            continue;

        var equals = Expression.Equal(
            Expression.Property(parameter, property.Name),
            Expression.Constant(value));

        body = body == null ? equals : Expression.AndAlso(body, equals);
    }

    if (body == null) // no filters
        body = Expression.Constant(true);

    var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);
    return lambda;
}

В случае, если все свойства в Ledger равны нулю, он вернет x => true, эта лямбда не будет ничего фильтровать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...