c# - Linq IQueryable 通用筛选器

标签 c# linq entity-framework c#-4.0

我正在为任何列/字段映射的查询中的 searchText 寻找通用过滤器

public static IQueryable<T> Filter<T>(this IQueryable<T> source, string searchTerm)
{
   var propNames = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public).Where(e=>e.PropertyType == typeof(String)).Select(x => x.Name).ToArray();


 //I am getting the property names but How can I create Expression for

 source.Where(Expression)
}

这里我给大家举个例子

现在从我在 Asp.net MVC4 中的 HTML5 表中,我提供了一个搜索框来过滤输入文本的结果,它可以匹配以下任何列/菜单类属性值,我想在服务器中进行此搜索side ,我该如何实现它。

EF 模型类

 public partial class Menu
    {
        public int Id { get; set; }
        public string MenuText { get; set; }
        public string ActionName { get; set; }
        public string ControllerName { get; set; }
        public string Icon { get; set; }
        public string ToolTip { get; set; }
        public int RoleId { get; set; }

        public virtual Role Role { get; set; }
    }

最佳答案

您可以使用表达式:

private static Expression<Func<T, bool>> GetColumnEquality<T>(string property, string term)
{
    var obj = Expression.Parameter(typeof(T), "obj");        

    var objProperty = Expression.PropertyOrField(obj, property);
    var objEquality = Expression.Equal(objProperty, Expression.Constant(term));

    var lambda = Expression.Lambda<Func<T, bool>>(objEquality, obj);

    return lambda;
}

public static IQueryable<T> Filter<T>(IQueryable<T> source, string searchTerm)
{
    var propNames = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public)
                             .Where(e => e.PropertyType == typeof(string))
                             .Select(x => x.Name).ToList();

    var predicate = PredicateBuilder.False<T>();

    foreach(var name in propNames)
    {
        predicate = predicate.Or(GetColumnEquality<T>(name, searchTerm));
    }

    return source.Where(predicate);
}

结合名字PredicateBuilder来自 C# 的 NutShell。这也是 LinqKit 的一部分.

例子:

public class Foo
{
    public string Bar { get; set; }
    public string Qux { get; set; }
}

Filter<Foo>(Enumerable.Empty<Foo>().AsQueryable(), "Hello");

// Expression Generated by Predicate Builder
// f => ((False OrElse Invoke(obj => (obj.Bar == "Hello"), f)) OrElse Invoke(obj => (obj.Qux == "Hello"), f))

关于c# - Linq IQueryable 通用筛选器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17832989/

相关文章:

c# - 我应该在 SQL 中还是在 LINQ 中执行 Where 子句?

.net - 存储过程在 Entity Framework 中很慢

c# - 急切加载自引用表

C# 与 VB.NET - 空结构的处理

c# - 为什么这种编译方式有所不同?

c# - 如何确保 Linq to Sql 不会覆盖或违反不可为 null 的数据库默认值?

c# - Entity Framework 6 中的 Fluent Api 不兼容 Entity Framework Core

c# - 类继承/方法覆盖

c# - C++ 中的 nullptr 与 C# 中的 null 相同吗?

c# - 强制 Entity Framework 使用 datetime 而不是 datetime2