使用linq或c#过滤数据表动态/多条件?

时间:2015-02-05 17:48:15

标签: c# linq

我有数据表dtResult,它的列是

BuildSequence,
Build#, 
BOptions,
BJob, 
LogID BType, 
BTypeKey, 
BComponentName, 
BCKey, 
RName, 
Rkey, 
RDescrip, 
RStatus, 
BuildMatchExp,
VPart, 
PNumber, 
SName, 
SKey, 
OName, 
OKey, 
Date

现在我有几个过滤器,这些过滤器是动态创建的,然后用户可以选择那些过滤器。这些过滤器是dtResult的列名。我有选定的过滤器列表,列表包含FilterName及其值。我的问题基于选定的过滤器如何过滤dtResult?由于这些过滤器不是恒定的,它们每次都在变化。每次更改我的意思是允许用户选择任何过滤器。

e.g;在一种情况下,用户可以选择BTypeKey和/或BCKey和/或Rkey,他们可以选择任何过滤器或不选择过滤器。

现在我可以根据“固定”列过滤dResult,但我不确定如何在动态过滤器上进行过滤?或者我如何使用linq来做到这一点?

任何帮助都会非常感激,因为我正在努力解决它。

到目前为止,在代码端我只有FilterList作为这个

FilterParameters filterlist = new FilterParameters(); 
filterlist.Add(new FilterParameter(this._BuildSequence, this._BuildSequenceName, FilterParameterTypes.Guid, FilterComparisonTypes.BuildSequence)); 
filterlist.Add(new FilterParameter(this._BCKey, this._BComponentName, FilterParameterTypes.Guid, FilterComparisonTypes.BCKey)); 
filterlist.Add(new FilterParameter(this._BTypeKey, base.BTypeName, FilterParameterTypes.Guid, FilterComparisonTypes.BTypeKey)); 
return filterlist; 

由于

2 个答案:

答案 0 :(得分:0)

我认为我接近这种方式的方法是让Filter对象作用于基本查询返回的IQueryable。然后将Filter对象映射到用户选择的过滤器。

例如:

class SomeDbContext : DbContext
{
    public IDbSet<Person> People { get; set; }
}

class Person
{
    public string Foreame { get; set; }
    public string Surname { get; set; }
    public int Age { get; set; }
}

abstract class PersonFilter
{
    public abstract IQueryable<Person> Filter(IQueryable<Person> query, string value);
}

class PersonForenameFilter : PersonFilter
{
    public override IQueryable<Person> Filter(IQueryable<Person> query, string value)
    {
        return query.Where(t => t.Foreame == value);
    }
}

class PersonAgeFilter : PersonFilter
{
    public override IQueryable<Person> Filter(IQueryable<Person> query, string value)
    {
        return query.Where(t => t.Age.ToString() == value);
    }
}

然后,您可以使用用户可选择的友好标签和Filter对象之间的词典来创建映射。然后你就做了:

string filterValue = "Dave";
var someFilter = new PersonForenameFilter();
var baseQuery = dbContext.People;
var filteredQuery = someFilter.Filter(baseQuery, filterValue);

其中someFilter实际上是从映射字典中检索的。

另请注意,这是可组合的,因此您可以应用多个过滤器。

答案 1 :(得分:0)

感谢@MethodMan,您的DataTable.Select方法确实有效,我使用

将我的Filterlist转换为表达式
var a = filterList.GroupBy(g => g.ParameterName).Select(gr => 
    string.Format("{0}={1}", gr.First().ParameterName, string.Join(",", gr.Select(g => g.Value))));
var b = string.Join(" And ", a.ToArray());

但是,我仍然坚持将SQL参数传递给存储过程,因为其中一个参数是csv(我在数据库端使用了Split用于csv)而Select方法的表达式已经与ID=1Name='abc'以及Address='here'city='there'类似,但如果您希望Name为'abc'或'xyz',则需要“..和Name='abc'Name='xyz',但我的逗号分隔值为Name={'abc,xyz'},我无法将Name转换为Name='abc'Name='xyz'

相关问题