2016-11-18 16 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; 
    } 
} 
相關問題