【问题标题】:Casting generic datatable to typed datatable将通用数据表转换为类型化数据表
【发布时间】:2010-11-26 18:48:34
【问题描述】:
我需要重用客户端规定的 DataAccess 方法。此方法返回一个香草数据表。
我想将此数据表转换为我的 Typed 数据表。列的数量及其类型将匹配。
异常消息“无法将 'System.Data.DataTable' 类型的对象转换为 'MarketValueDataTable' 类型。”
很清楚,但是如何解决呢?
查看了casting-a-base-type-to-a-derived-type,但不知道如何实现。
我无法使用数据读取器填充数据表,只能使用客户端的 DataAccess 方法。
【问题讨论】:
标签:
c#
datatable
strongly-typed-dataset
【解决方案1】:
只有当方法返回的表实际上是MarketValueDataTable 的实例时,转换才能起作用。如果不是,您所能做的就是将数据复制到MarketValueDataTable 的实例中。例如,您可以使用 Merge 方法:
DataTable data = GetData();
MarketValueDataTable myData = new MarketValueDataTable();
myData.Merge(data);
【解决方案2】:
使用这个方便的函数将常规的DataTable 转换为类型化的DataTable。
VB
Public Shared Function ConvertToTypedDataTable(Of T As {Data.DataTable, New})(dtBase As Data.DataTable) As T
Dim dtTyped As New T
dtTyped.Merge(dtBase)
Return dtTyped
End Function
用法
Dim dtTyped = ConvertToTypedDataTable(Of dataset1.MyTypedDataTable)(MyUntypedDataTable)
C#
public static T ConvertToTypedDataTable<T>(System.Data.DataTable dtBase) where T : Data.DataTable, new()
{
T dtTyped = new T();
dtTyped.Merge(dtBase);
return dtTyped;
}
用法
dataset1.MyTypedDataTable dtTyped = ConvertToTypedDataTable<dataset1.MyTypedDataTable>(MyUntypedDataTable);
【解决方案3】:
您不能将 DataTable 转换为 MarketValueDataTable,原因很简单,因为它不继承自它。
您需要做的是实例化一个新的 MarketValueDataTable,然后将 DataTable 中的数据复制到其中。
尝试类似:
MarketValueDataTable myTable = new MarketValueDataTable();
StringWriter writer = new StringWriter();
theDataTable.WriteXml(writer);
myTable.ReadXml(new StringReader(writer.ToString()));
(我没有测试过)
【解决方案4】:
如果您的数据表是通用表,则不能将其转换为 MarketValueDataTable。
您可以尝试的一件事是创建一个新的 MarketValueDataTable 对象并手动向其中添加行。通过遍历通用数据表的行,然后遍历每行的列,您可以使用反射来设置新 MarketValueDataTableRow 的属性值。
类似于以下内容(警告 - 伪代码):
MarketValueDataTable mv = new MarketValueDataTable();
foreach(DataRow row in table.Rows)
{
MarketValueDataTableRow mvrow = mv.NewRow();
foreach(DataColumn col in table.Columns)
{
PropertyInfo colProperty = mvrow.GetType().GetProperty(col.Name);
colProperty.SetValue(mvRow, row[col]);
}
mv.Rows.Add(mvrow);
}
你大概明白了。遍历通用表的行并使用反射在特定类型的数据行中查找匹配的属性。这应该可行(我之前使用过相同的方法),但必须修改代码以满足您的要求。