2016-11-18 5 views
1

他の質問によく似ていますが。 Other questionジェネリック拡張メソッドのドット表記で文字列の列名を使用してIQueryableをフィルタリングする方法

これを行う方法と、ネストされたオブジェクトでドット表記をサポートする方法が不思議です。私の現在のIQueryableへの拡張は次のようになります。

public static IQueryable<T> WherePropStringContains<T>(this IQueryable<T> query, string propertyName, string contains) 
    { 
     var parameter = Expression.Parameter(typeof(T), "x"); 
     var propertyExpression = Expression.Property(parameter, propertyName); 
     var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); 
     var someValue = Expression.Constant(contains, typeof(string)); 
     var containsExpression = Expression.Call(propertyExpression, method, someValue); 
     var lmd = Expression.Lambda<Func<T, bool>>(containsExpression, parameter); 

     return query.Where(lmd); 
    } 

私は、私は、文字列やジェネリックを使用していなかった場合は「User.Name.Firstは」query.where(x => x.User.Name.First.Contains(contains)

のように見えるかもしれないようなものをサポートするために、プロパティ名を希望おかげ

+1

これはあなたのために働く必要があります。http://stackoverflow.com/a/39183597/861716有望に見える –

+0

を、私はそれを試してみますよ – matthewdaniel

答えて

0

これを行いますあなたが探しているものに似ていますか?

public static class Extensions { 
    public static IQueryable<T> WherePropStringContains<T>(this IQueryable<T> queryable, String name, String value) { 
     IEnumerable<String> propertyNames = name.Split('.'); 

     return queryable.Where(x => ObjectChainHasProperties(x, propertyNames, value)); 
    } 

    private static bool ObjectChainHasProperties(Object obj, IEnumerable<String> propertyNames, String value) { 
     IEnumerator<String> enumerator = propertyNames.GetEnumerator(); 

     while (obj != null && enumerator.MoveNext()) { 
      obj = obj.GetType().GetProperties() 
       .Where(p => p.Name == enumerator.Current) 
       .FirstOrDefault()? 
       .GetValue(obj); 
     } 

     return (obj as String) == value; 
    } 
} 
関連する問題