[.NET]透過DataTableExtensions.CopyToDataTable時,發生「來源未包含 DataRow」錯誤的解決方式!
今天同事問說,他透過Linq操作DataTable,如果查不到資料,然後呼叫CopyToDataTable時,會發生以下的錯誤,
System.InvalidOperationException: 來源未包含 DataRow。
於 System.Data.DataTableExtensions.LoadTableFromEnumerable[T](IEnumerable`1 source, DataTable table, Nullable`1 options, FillErrorEventHandler errorHandler)
於 System.Data.DataTableExtensions.CopyToDataTable[T](IEnumerable`1 source)
解決方式當然就是先判斷有沒有資料,有資料才呼叫CopyToDataTable。
另外,也可以先建立DataTable變數當作是CopyToDataTable Method的參數,就不用特別去判斷有沒有資料了哦! 如下,
先準備資料,
private DataTable GetSourceData()
{
DataTable result = new DataTable("OrgData");
result.Columns.Add("Node", typeof(string));
result.Columns.Add("ParentNode", typeof(string));
//加入資料 依Tree排
result.Rows.Add("Root", string.Empty);
result.Rows.Add("Node1", "Root");
result.Rows.Add("Node2", "Root");
result.Rows.Add("Node3", "Root");
result.Rows.Add("Node11", "Node1");
result.Rows.Add("Node12", "Node1");
result.Rows.Add("Node13", "Node1");
result.Rows.Add("Node14", "Node1");
result.Rows.Add("Node111", "Node11");
result.Rows.Add("Node112", "Node11");
result.Rows.Add("Node113", "Node11");
result.Rows.Add("Node21", "Node2");
result.Rows.Add("Node22", "Node2");
result.Rows.Add("Node221", "Node22");
result.Rows.Add("Node222", "Node22");
result.Rows.Add("Node23", "Node2");
result.Rows.Add("Node24", "Node2");
result.Rows.Add("Node31", "Node3");
result.Rows.Add("Node32", "Node3");
result.Rows.Add("Node321", "Node32");
result.Rows.Add("Node322", "Node32");
return result;
}
各種測試方式,
DataTable orgData = GetSourceData();
//有資料時,直接呼叫CopyToDataTable不會發生錯誤
var dtFilterRoot = (from row in orgData.AsEnumerable()
where row.Field<string>("ParentNode") == "Root"
select row).CopyToDataTable();
//沒資料測試-1
try
{
var dtFilterNothing = (from row in orgData.AsEnumerable()
where row.Field<string>("ParentNode") == "RootAbc"
select row).CopyToDataTable();
}
catch (Exception ex)
{
//會發生「System.InvalidOperationException: 來源未包含 DataRow」的錯誤
MessageBox.Show(ex.ToString());
}
//沒資料測試-2
var filterNothing2Rows = (from row in orgData.AsEnumerable()
where row.Field<string>("ParentNode") == "RootAbc"
select row);
DataTable dtFilterNothing2;
//先判斷有資料才Copy
if (filterNothing2Rows.Any())
{
//有資料才Copy
dtFilterNothing2 = filterNothing2Rows.CopyToDataTable();
}
//沒資料測試-3
var dtFilterNothing3 = orgData.Clone();
//把dataTable變數dtFilterNothing3 當CopyToDataTable的參數傳進去
(from row in orgData.AsEnumerable()
where row.Field<string>("ParentNode") == "RootAbc"
select row).CopyToDataTable(dtFilterNothing3, LoadOption.PreserveChanges);
不知大家是否有其他的想法呢?
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^