使用LINQ的通用过滤器类

时间:2015-12-03 21:10:10

标签: linq generics filtering

我在整个应用程序中都有一个使用EntityFramework和winform的过滤器政治,现在我需要设计一个类来促进过滤,就像那样

public class TextPredicatFilter<T>
{ 
    List<T> _list;
    List<CheckedPredicat> _listPredicat= new List<CheckedPredicat>();
    bool _active = true; 
    public TextPredicatFilter(BindingSource bs ,TextBox txtFilter, List<T> bindingList)
    {
        _list = bindingList;

        txtFilter.TextChanged += delegate
        {
            if (!_active)
                return; 
            foreach(CheckedPredicat prd in _listPredicat)
            {
                if(prd.CheckControl.Checked)
                {
                     bs.DataSource = new BindingList<T>(_list.Where(t=>t.GetType().GetProperty(prd.ColumnName).GetConstantValue().ToString() == txtFilter.Text).ToList<T>());
                }
            }
        };
    }
    public void Add(CheckedPredicat chkPredicat)
    {
        _listPredicat.Add(chkPredicat);
    }}

public class CheckedPredicat
{
    public RadioButton CheckControl { get; set; }
    public string ColumnName { get; set; }
    public bool UseLike { get; set; }       
}

但这不起作用!任何想法?

2 个答案:

答案 0 :(得分:2)

首先,使其独立于任何UI实现。您不需要BindingSources或RadioButtons来构建动态数据库查询。使用原始数据,过滤它们,然后将结果重新绑定到您今天碰巧使用的任何UI框架......或明天。

其次,保持简单。您只需要一系列列名,搜索词和布尔值。您只是过滤。这并不需要一个全新的班级TextPredicatFilter来完成这项工作。

第三,要回答您的问题,请使用Dynamic LINQ构建查询。 (史蒂夫在我准备的时候也推荐)。

让我们说你有这个课程:

public class Predicate
{
    public string ColumnName  { get; set; }
    public string FilterValue { get; set; }
    public bool UseLike { get; set; }
}

然后构建查询的所有代码都如下所示:

using System.Linq.Dynamic;

IQueryable<Company> companies = context.Companies;

var predicates = new Predicate[]
{
    new Predicate { ColumnName = "Name", FilterValue = "o", UseLike = true },
    new Predicate { ColumnName = "Code", FilterValue = "c", UseLike = false },
};

foreach (var pred in predicates)
{
    var predicateString = pred.UseLike
                            ? "{0}.Contains(@{1})"
                            : "{0} = @{1}";
    companies = companies
        .Where(string.Format(predicateString, pred.ColumnName, 0), pred.FilterValue);
}

现在您可以将companies(可能与ToList())绑定到BindingList或您要使用的任何类型的显示。

答案 1 :(得分:1)

您可能需要查看Dynamic Linq,这样就可以编写像这样的过滤器;

using System.Linq.Dynamic; //Import the Dynamic LINQ library

var result = myQuery
    .Where("Field1=\"SomeValue\"")
    .Select("new (Field1, Field2)");

我认为你可以直接在WHERE子句中编写startswith / endswith;

之类的东西
var result = myQuery
   .Where("Field1.StartsWith(\"somevalue\") || Field1.EndsWith(\"somevalue\")")

但我不确定。