Ed *_*nek 1 c# lambda extension-methods
我从CodePlex上的这个例子开始使用IQueryable扩展方法.
我认为我需要的是一个IQueryable扩展方法到"Where",方法签名如下所示:
public static IQueryable<T> Where<T>(this IQueryable<T> source, string columnName, string keyword)
并有效地做到这一点(假设T.columnName的类型为string):
source.Where(p => p.ColumnName.Contains("keyword"))
使用上面的CodePlex示例,我想我理解他如何使OrderBy方法工作,但我的问题似乎有点复杂,我不知道如何让Contains("关键字")部分工作.
提前致谢,
--ed
更新:9/13/2010太平洋标准时间下午6:26
我认为以下内容可行,但最终得到一个NotSupportedException(LINQ to Entities中不支持LINQ表达式节点类型'Invoke'.)当我通过Count()执行表达式时.有任何想法吗?
    public static IQueryable<T> Where<T>(this IQueryable<T> source, string columnName, string keyword)
    {
        var type = typeof(T);
        var property = type.GetProperty(columnName);
        if (property.PropertyType == typeof(string))
        {
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var sel = Expression.Lambda<Func<T, string>>(propertyAccess, parameter);
            var compiledSel = sel.Compile();
            return source.Where(item => compiledSel(item).Contains(keyword));
        }
        else
        {
            return source;
        }
    }
public static IQueryable<T> Where<T>(
    this IQueryable<T> source, string columnName, string keyword)
{
    var arg = Expression.Parameter(typeof(T), "p");
    var body = Expression.Call(
        Expression.Property(arg, columnName),
        "Contains",
        null,
        Expression.Constant(keyword));
    var predicate = Expression.Lambda<Func<T, bool>>(body, arg);
    return source.Where(predicate);
}
好几年后,但如果有人仍然需要这个,这里是:
    public static IQueryable<T> Has<T>(this IQueryable<T> source, string propertyName, string keyword)
    {
        if (source == null || propertyName.IsNull() || keyword.IsNull())
        {
            return source;
        }
        keyword = keyword.ToLower();
        var parameter = Expression.Parameter(source.ElementType, String.Empty);
        var property = Expression.Property(parameter, propertyName);
        var CONTAINS_METHOD = typeof(string).GetMethod("Contains", new[] { typeof(string) });
        var TO_LOWER_METHOD = typeof(string).GetMethod("ToLower", new Type[] { });
        var toLowerExpression = Expression.Call(property, TO_LOWER_METHOD);
        var termConstant = Expression.Constant(keyword, typeof(string));
        var containsExpression = Expression.Call(toLowerExpression, CONTAINS_METHOD, termConstant);
        var predicate = Expression.Lambda<Func<T, bool>>(containsExpression, parameter);
        var methodCallExpression = Expression.Call(typeof(Queryable), "Where",
                                    new Type[] { source.ElementType },
                                    source.Expression, Expression.Quote(predicate));
        return source.Provider.CreateQuery<T>(methodCallExpression);
    }
我打电话给我的方法"Has"只是为了保持简短,样本用法:
filtered = filtered.AsQueryable().Has("City", strCity)
并且您可以连接以使其更具表现力:
filtered = filtered.AsQueryable().Has("Name", strName).Has("City", strCity).Has("State", strState);
顺便说一句,附加到字符串的"IsNull()"只是另一种简单的扩展方法:
    public static Boolean IsNull(this string str)
    {
        return string.IsNullOrEmpty(str);
    }
| 归档时间: | 
 | 
| 查看次数: | 11874 次 | 
| 最近记录: |