2015-02-05 65 views
0

我有数据表dtResult和它的列使用linq或c#过滤数据表的动态/多重条件?

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

现在我有一些过滤器,这些过滤器是动态创建,然后用户可以选择这些过滤器。这些过滤器是dtResult的列名称。我有选定的过滤器列表,列表包含FilterName和它的值。我的问题是基于选定的过滤器如何我可以过滤dtResult?由于这些过滤器并不稳定,所以每次都在变化。改变每次我的意思是允许用户选择任何过滤器。

例如;在一种情况下,用户可以选择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; 

感谢

+0

你是否在'C#DataTable Filter'上做过谷歌搜索? [MSDN DataTable.Select Method()](https://msdn.microsoft.com/en-us/library/det4aw50%28v=vs.110% 29.aspx) – MethodMan 2015-02-05 17:53:24

+0

@MethodMan是的,我做了,但我的问题仍然在动态与固定。就像我将如何表达过滤一样。指导将不胜感激 – user2726374 2015-02-05 18:00:47

+0

你可以显示一些代码,你正在做什么..我很确定这可以通过使用变量来完成..如果没有,那么我会建议创建一个实现/利用'ISNULL'检查的存储过程,并且你可以建立你的查询/过滤,这样我不知道你是否也可以通过创建一个'enum'并通过获取字符串名称的枚举..我需要看看你目前正在试图看看我的建议是否会工作.. – MethodMan 2015-02-05 18:03:36

回答

0

我想我会处理这个的方法是有作用于IQueryable的返回由Filter对象基本查询。然后将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); 
    } 
} 

然后你就可以创造一个友好的标签可以由用户选择和过滤对象之间用说一个字典映射。那么你只需要:

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

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

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

+0

我工作的winforms不是MVC对不起,我没有提及它。我的数据表是存储过程的结果,它不是模型(模型类)。 – user2726374 2015-02-05 18:34:38

0

感谢@MethodMan,你DataTable.Select方法做的工作,我用

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()); 

但是转换我Filterlist来表达,我仍然坚持通过SQL参数给存储过程,因为参数之一是CSV(我已经使用Split在数据库端CSV),并表达了Select方法是像ID=1Name='abc'Address='here'city='there'但如果你想Name是“ABC”或“某某”你需要” ..和Name='abc'或​​但它的逗号对我来说,我的配对值为Name={'abc,xyz'},我无法将Name转换为Name='abc'或​​。