3

一般的なIQueryableリストで動的フィルタリングを実行するために使用している次のコードブロックがあります

    private static MethodInfo miTL = typeof(String).GetMethod("ToLower", Type.EmptyTypes);

    public static IQueryable<T> Where<T>(IQueryable<T> source, string member, object value)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        if (member == null)
        {
            throw new ArgumentNullException("member");
        }
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }

        if (value is string && !string.IsNullOrWhiteSpace(value.ToString()))
        {
            //If the type is string, force lowercase equals comparison for both sides.
            value = value.ToString().ToLower();

            var parameter = Expression.Parameter(typeof(T), "item");
            var parameterProperty = Expression.Property(parameter, member);

            //ToLower dynamic expression
            var dynamicExpression = Expression.Call(parameterProperty, miTL);

            var constantValue = Expression.Constant(value);
            var equalsExpression = Expression.Equal(dynamicExpression, constantValue);

            var lambdaExpression = Expression.Lambda<Func<T, bool>>(equalsExpression, parameter);

            return source.Where(lambdaExpression);
        }
        else
        {
            var item = Expression.Parameter(typeof(T), "item");
            var prop = Expression.Property(item, member);
            var soap = Expression.Constant(value);
            var equal = Expression.Equal(prop, soap);
            var lambda = Expression.Lambda<Func<T, bool>>(equal, item);
            return source.Where(lambda);
        }
    }

これはすべて正常に機能します-ソースにnull値が含まれている可能性を除けば、null参照例外が返されます。

これは直接変換されます(フィールドが "Counterparty"の場合:-{item =>(item.Counterparty.ToLower()== "カウンターパーティの名前")}

ラムダ式の形式で実際に必要なのは:-

{item =>!string.IsNullEmptyOrWhitespace(item.Counterparty)&&(item.Counterparty.ToLower()== "カウンターパーティの名前")}

これを動的に達成する方法はありますか?

- 審査 -

これは、はるかに優れた文字列を使用した置換コード全体です。

    public static IQueryable<T> Where<T>(IQueryable<T> source, string member, object value)
    {
        if (source == null)
        {
            throw new ArgumentNullException("source");
        }
        if (member == null)
        {
            throw new ArgumentNullException("member");
        }
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }

        if (value is string && !string.IsNullOrWhiteSpace(value.ToString()))
        {
            var parameter = Expression.Parameter(typeof(T), "item");
            var parameterProperty = Expression.Property(parameter, member);

            var body =
                Expression.AndAlso(
                    Expression.Not(
                        Expression.Call(typeof(string), "IsNullOrEmpty", null, parameterProperty)
                    ),
                    Expression.Call(typeof(string), "Equals", null,
                        parameterProperty, Expression.Constant(value),
                        Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase))
                );

            var body2 = Expression.Call(typeof(string), "Equals", null,
                parameterProperty, Expression.Constant(value),
                Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase));

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

            return source.Where(lambdaExpression);
        }
        else
        {
            var item = Expression.Parameter(typeof(T), "item");
            var prop = Expression.Property(item, member);
            var soap = Expression.Constant(value);
            var equal = Expression.Equal(prop, soap);
            var lambda = Expression.Lambda<Func<T, bool>>(equal, item);
            return source.Where(lambda);
        }
    }
4

1 に答える 1

3

直訳すると次のようになります。

var body =
    Expression.AndAlso(
        Expression.Not(
            Expression.Call(typeof(string), "IsNullOrWhiteSpace", null,
                                                       parameterProperty)
        ),
        Expression.Equal(
            Expression.Call(parameterProperty, "ToLower", null),
            Expression.Constant("name of counterparty")
        )
    );

ただし、さまざまなstring.Equalsオーバーロードを確認することをお勧めします。例えば:

var body = Expression.Call(typeof(string), "Equals", null,
    parameterProperty, Expression.Constant("name of counterparty"),
    Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase));
于 2013-02-12T08:44:42.307 に答える