如何将旧DataTable中只需要的行复制到具有不同结构的新DataTable行



我有一个要求,需要将现有的DataTable行/值复制到新的DataTable,新数据表具有自定义(不同列名(结构/架构,因为我们需要稍后将此新数据表数据导出到Excel文件。

为了将所需的列值复制到新的DataTable,我创建了字符串Array,其中包含现有DataTable所需的列名(我们需要将数据复制到新DataTable的列(,如下所示。

string[] selectedColumns = new[] { "SUPPLIER_NAME", "SUPPLIER_NO", "CONFIRMATION_NO", "RELEASE_NO", "WCO_INVOICE_NO",
"CUSTOMER_BILLED", "BALANCE_TOBILL", "SUPP_INVOICE_NO", "SUPPLIER_PAID", "BALANCE_COST" };   //TODO Add columns "WCO_INVOICE_DATE", "SUPPLIER_INVOICE_DATE" later.

为了获得所需的DataTable,我创建了一个方法,通过传递现有的DataTable和现有DataTable列名的选定列作为参数,该方法将被如下调用。

DataTable _dtPrjLedgerExportData = ControllerClass.dtProjectLedgerExport(dtfilter, selectedColumns);

ControllerClassdtProjectLedgerExport方法将返回新创建的DataTable,即具有自定义列名和从现有DatTable中提取的值的DataTable,

新的DataTable还包含两个新列(WCO_Invoice_Date、Supplier_Invoice_Date(,它们具有默认的空白值(根据代码设置(。

public static DataTable dtProjectLedgerExport(DataTable dtToExport, string[] selectedColumns)
{
DataTable dt = new DataTable();
dt.Columns.Add("Supplier");
dt.Columns.Add("Supplier_No");
dt.Columns.Add("Confirmation_Number");
dt.Columns.Add("Release_Number");
dt.Columns.Add("WCO_Invoice_No");
dt.Columns.Add("WCO_Invoice_Date");
dt.Columns.Add("Customer_Billed_Amt");
dt.Columns.Add("Balance_Remaining_to_Bill");
dt.Columns.Add("Supplier_Invoice_Number");
dt.Columns.Add("Supplier_Invoice_Date");
dt.Columns.Add("Supplier_Paid_Amt");
dt.Columns.Add("Remaining_Cost_Dollar_Balance");
//temporarily set default value for non-existing rows 
dt.Columns["WCO_Invoice_Date"].DefaultValue = string.Empty;
dt.Columns["Supplier_Invoice_Date"].DefaultValue = string.Empty;
//Copy rows to dt
if (dtToExport != null && dtToExport.Rows.Count > 0)
dt = new DataView(dtToExport).ToTable(false, selectedColumns);
return dt;
}

问题:上面的代码没有按预期工作,它正在返回具有相同结构的现有DataTable的数据。

为了得到预期的结果,上面的代码需要做哪些更改?

我会使用这种方法:

public static DataTable DtProjectLedgerExport(DataTable dtToExport, string[] selectedColumns, params string[] additionalColumns)
{
DataTable dt = dtToExport.Copy(); // add columns and data
List<DataColumn> removeColumns = dt.Columns.Cast<DataColumn>()
.Where(c => !selectedColumns.Contains(c.ColumnName, StringComparer.InvariantCultureIgnoreCase))
.ToList();
removeColumns.ForEach(dt.Columns.Remove);
foreach (string colName in additionalColumns)
{
DataColumn newColumn = new DataColumn(colName);
newColumn.DefaultValue = string.Empty;
dt.Columns.Add(newColumn);
}
return dt;
}

在注释中声明每个表中有不同的列名后。。。(说真的,这是一条关键信息,哈哈(!唯一的方法是自己为每一列基本地映射值,就像这样

public static DataTable dtProjectLedgerExport(DataTable dtToExport)
{
DataTable dt = new DataTable();
dt.Columns.Add("Supplier");
dt.Columns.Add("Supplier_No");
dt.Columns.Add("Confirmation_Number");
dt.Columns.Add("Release_Number");
dt.Columns.Add("WCO_Invoice_No");
dt.Columns.Add("WCO_Invoice_Date");
dt.Columns.Add("Customer_Billed_Amt");
dt.Columns.Add("Balance_Remaining_to_Bill");
dt.Columns.Add("Supplier_Invoice_Number");
dt.Columns.Add("Supplier_Invoice_Date");
dt.Columns.Add("Supplier_Paid_Amt");
dt.Columns.Add("Remaining_Cost_Dollar_Balance");
foreach (var expRow in dtToExport.Rows)
{
var row = dt.NewRow();
row["Supplier"] = expRow["Supplier_Name"];
//repeat for all columns you want.
dt.Rows.Add(row);
}
return dt;
}

当然,因为您最终完全覆盖了dt。您应该在循环中枚举dtToExport中的行,并在dt中创建新行,并为所需的每个字段分配值。

最新更新