使用DataTable的过滤版本的最佳方法是什么?

时间:2018-02-22 07:38:49

标签: .net datatable architecture ado.net dataview

我的DataSet包含DataTable个,dt1dt2dt3dt4。我也有3 DataRelation这样:

|Parent|Child|
|  d1  |  d2 |
|  d2  |  d3 |
|  d2  |  d4 |

我的MasterClass将此DataSet传递给多个班级,每个班级都需要使用DataSet执行不同的操作。但是,在传递DataSet之前,MasterClass需要在dt1上执行过滤,因为每个类都需要使用过滤版本的dt1。请注意,我无法更新dt1,因为我需要在同一DataTable上执行不同的过滤器。在下图中,我尝试将结构可视化:

The Architecture

我的问题是:将过滤后的dt1传递给Class A..B的最佳方法是什么?

我想到的第一个解决方案是在dt1中创建DataSet的副本,并将过滤后的版本存储在其中,比如FilteredDt1,但是,我不知道我想在内存中有冗余数据/ DataRow

从我在微软的文档中看到的内容,我认为我可以在DataView的帮助下做得更好,我将DataView作为第二个参数传递给类,但我没有得到我怎么做,也从软件架构的角度来看。

我遇到的

问题

  • 如果我使用DataRelation,是否仍然可以使用DataView
  • 是否可以在DataViewDataTable
  • 上运行联接

我对ADO.NET很陌生,如果你纠正我,如果我的问题中有任何错误/错误的假设,我会非常感激。

1 个答案:

答案 0 :(得分:0)

您可以使用linq:

var filtered1 = MyDataSet.Tables["d1"].Rows.OfType<DataRow>()
                .Where(r => r["Column"] = value);

var filtered2 = MyDataSet.Tables["d1"].Rows.OfType<DataRow>()
                .Where(r => r["OtherColumn"] = differentValue);

现在filtered1将返回IEnumerable<DataRow>,其中Column = value
filtered2将返回IEnumerable<DataRow> OtherColumn = differentValue

原始数据表保持不变。

请注意,在使用OfType扩展方法之前,我必须使用Where扩展方法,因为Rows属性类型为DataRowCollection但未实现通用IEnumerable<T>接口,只有非通用IEnumerable(和ICollection)接口。

<强>更新

正在寻找一种在不更改源数据表的情况下返回已过滤数据表的方法我遇到DataTable类的AsEnumerable扩展方法,它返回IEnumerable<DataRow>(),所以我的建议可以简化为...MyDataSet.Tables["d1"].AsEnumerable().Where...

另外,我找到了一种方法,只使用过滤后的行创建数据表的副本。您所做的是使用接受DataTableRowFilterSortDataViewRowState的{​​{3}},然后调用它的DataView constructor方法返回一个新的数据表 请注意,这将为内存中的数据行创建新副本,因为DataRow只能属于单个DataTable

但是,请注意我建议使用IEnumerable<T>,其中T是您创建的特定类型ToTable,而不是直接使用DataTable。这将使您的生活更安全,更轻松。