使用过滤版本的 DataTable 的最佳方式是什么?
What is the best way to use a filtered version of a DataTable?
我有一个包含 4 个 DataTable
的 DataSet
,比如 dt1
、dt2
、dt3
、dt4
。我也有 3 个这样的 DataRelation
:
|Parent|Child|
| d1 | d2 |
| d2 | d3 |
| d2 | d4 |
我的 MasterClass
将此 DataSet
传递给多个 class,每个 class 需要使用 DataSet
执行不同的操作。但是,在通过 DataSet
之前,MasterClass
需要对 dt1
执行过滤,因为每个 class 都需要与 dt1
的过滤版本一起使用。请注意,我无法更新 dt1
,因为我需要对同一个 DataTable
执行不同的过滤器。在下图中,我尝试可视化结构:
我的问题是:将过滤后的 dt1
传递给 Class A..B
的最佳方法是什么?
我想到的第一个解决方案是在我的 DataSet
中创建一个 dt1
的副本,并将过滤后的版本存储在其中,比如 FilteredDt1
,但是,我不想在内存中有冗余数据/DataRow
s。
根据我在 Microsoft 文档中阅读的内容,我认为在 DataView
的帮助下我可以做得更好,我将 DataView
作为第二个参数传递到 classes,但我不知道我该怎么做,也是从 软件架构 的角度来看。
遇到的问题:
- 如果我使用
DataView
,是否仍然可以使用 DataRelation
?
- 是否可以 运行 连接
DataView
和 DataTable
?
我是 ADO.NET
的新手,如果您纠正我,如果我的问题中有任何错误/不正确的假设,我将非常感激。
你可以使用 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
将 return 一个 IEnumerable<DataRow>
其中 Column = value
,
filtered2
将 return 一个 IEnumerable<DataRow>
其中 OtherColumn = differentValue
,
而你的原始数据table保持不变。
请注意,在使用 Where
扩展方法之前,我必须使用 OfType
扩展方法,因为 Rows
属性 的类型为 DataRowCollection
不实现通用 IEnumerable<T>
接口,仅实现 not-generic IEnumerable
(和 ICollection
)接口。
更新:
寻找一种方法来 return 过滤数据 table 而不更改源数据 table 我遇到了 AsEnumerable
DataTable
的扩展方法] class,其中 return 是 IEnumerable<DataRow>()
,所以我的建议可以简化为 ...MyDataSet.Tables["d1"].AsEnumerable().Where...
。
另外,我找到了一种方法,可以让您创建仅包含过滤行的数据副本 table。您所做的是使用 DataView
constructor that accepts DataTable
, RowFilter
, Sort
, and DataViewRowState
, and then call it's ToTable
方法 return 新数据 table.
请注意,这将为内存中的数据行创建新副本,因为 DataRow
只能属于单个 DataTable
.
但是,请注意,我建议使用 IEnumerable<T>
,其中 T
是您创建为 DTO 的特定类型,而不是直接使用 DataTable
。这将使您的生活更加安全和轻松。
我有一个包含 4 个 DataTable
的 DataSet
,比如 dt1
、dt2
、dt3
、dt4
。我也有 3 个这样的 DataRelation
:
|Parent|Child|
| d1 | d2 |
| d2 | d3 |
| d2 | d4 |
我的 MasterClass
将此 DataSet
传递给多个 class,每个 class 需要使用 DataSet
执行不同的操作。但是,在通过 DataSet
之前,MasterClass
需要对 dt1
执行过滤,因为每个 class 都需要与 dt1
的过滤版本一起使用。请注意,我无法更新 dt1
,因为我需要对同一个 DataTable
执行不同的过滤器。在下图中,我尝试可视化结构:
我的问题是:将过滤后的 dt1
传递给 Class A..B
的最佳方法是什么?
我想到的第一个解决方案是在我的 DataSet
中创建一个 dt1
的副本,并将过滤后的版本存储在其中,比如 FilteredDt1
,但是,我不想在内存中有冗余数据/DataRow
s。
根据我在 Microsoft 文档中阅读的内容,我认为在 DataView
的帮助下我可以做得更好,我将 DataView
作为第二个参数传递到 classes,但我不知道我该怎么做,也是从 软件架构 的角度来看。
遇到的问题:
- 如果我使用
DataView
,是否仍然可以使用DataRelation
? - 是否可以 运行 连接
DataView
和DataTable
?
我是 ADO.NET
的新手,如果您纠正我,如果我的问题中有任何错误/不正确的假设,我将非常感激。
你可以使用 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
将 return 一个 IEnumerable<DataRow>
其中 Column = value
,
filtered2
将 return 一个 IEnumerable<DataRow>
其中 OtherColumn = differentValue
,
而你的原始数据table保持不变。
请注意,在使用 Where
扩展方法之前,我必须使用 OfType
扩展方法,因为 Rows
属性 的类型为 DataRowCollection
不实现通用 IEnumerable<T>
接口,仅实现 not-generic IEnumerable
(和 ICollection
)接口。
更新:
寻找一种方法来 return 过滤数据 table 而不更改源数据 table 我遇到了 AsEnumerable
DataTable
的扩展方法] class,其中 return 是 IEnumerable<DataRow>()
,所以我的建议可以简化为 ...MyDataSet.Tables["d1"].AsEnumerable().Where...
。
另外,我找到了一种方法,可以让您创建仅包含过滤行的数据副本 table。您所做的是使用 DataView
constructor that accepts DataTable
, RowFilter
, Sort
, and DataViewRowState
, and then call it's ToTable
方法 return 新数据 table.
请注意,这将为内存中的数据行创建新副本,因为 DataRow
只能属于单个 DataTable
.
但是,请注意,我建议使用 IEnumerable<T>
,其中 T
是您创建为 DTO 的特定类型,而不是直接使用 DataTable
。这将使您的生活更加安全和轻松。