【问题标题】:Filter Datatable dynamic/multiple condition using linq or c#?使用 linq 或 c# 过滤数据表动态/多个条件?
【发布时间】:2016-12-16 17:08:07
【问题描述】:

我有数据表 dtResult,它的列是

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

现在我有几个过滤器,这些过滤器是动态创建的,然后用户可以选择这些过滤器。这些过滤器是 dtResult 的列名。我有选定过滤器的列表,列表包含过滤器名称及其值。我的问题是基于选定的过滤器我如何过滤 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; 

谢谢

【问题讨论】:

  • 你在C# DataTable FilterMSDN DataTable.Select Method()上做过谷歌搜索
  • @MethodMan 是的,我做到了,但我的问题仍然出现在动态与固定之间。就像我将如何表达过滤一样。指导将不胜感激
  • 你能显示一些关于你当前正在做什么的代码吗?我很确定这可以通过使用变量来完成。如果不是,那么我建议创建一个实现 / 的存储过程利用ISNULL 检查,您可以通过这种方式构建查询/过滤我想知道您是否也可以通过创建enum 并通过获取枚举的字符串名称来传递变量来做到这一点。我需要看看什么您目前正在尝试查看我的建议是否可行..
  • 目前我正在将这些过滤器传递给存储过程,但情况是有 4 个不同版本的 SQL 正在运行,我不确定我的存储过程是否可以在 SQL2000 上运行,但这些都在 SQL2005 及更高版本上运行,这就是为什么我正在将其切换为代码。目前我在存储过程中将过滤器作为 StoredProcedures 参数传递,默认为 Null。
  • 到目前为止,在代码方面,我只有 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));返回过滤器列表;

标签: c# linq


【解决方案1】:

我认为我解决此问题的方法是让 Filter 对象作用于基本查询返回的 IQueryable。然后将过滤器对象映射到用户选择的过滤器。

例如:

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 实际上是从映射字典中检索到的。

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

【讨论】:

  • 我正在使用 winforms 而不是 MVC 抱歉我之前没有提到它。我的数据表是存储过程的结果,它不是模型(模型类)。
【解决方案2】:

感谢@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());

但是,我仍然坚持将 SQL 参数传递给存储过程,因为其中一个参数是 csv(我在数据库端使用 Split 表示 csv)并且 Select 方法的表达式必须像 @ 987654324@ 和 Name='abc'Address='here'city='there' 但如果你希望 Name 是 'abc' 或 'xyz' 你需要 ".. 和 Name='abc'Name='xyz' 但它的逗号分隔值对我来说就像Name={'abc,xyz'} 一样,我无法将Name 转换为Name='abc'Name='xyz'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多