我有两个数据表,并希望连接这两个表来查找两列之间的差异,但是它会一直返回null并在CopyToDataTable方法中出错,因为您无法将null传递给它。我在此代码之前检查过TestOutput和ExpectedOutput表中的数据完全相同。 这是我的代码:
IEnumerable<DataRow> diff =
(from datarows1 in TestOutput.AsEnumerable()
join datarows2 in ExpectedOutput.AsEnumerable()
on datarows1.Field<String>("external_id") equals datarows2.Field<String>("external_id")
select new
{
KeyId = datarows1.Field<String>("external_id"),
Difference = datarows1.Field<Decimal>("quantity") - datarows2.Field<Decimal>("quantity")
}) as IEnumerable<DataRow>;
DataTable difference = diff.CopyToDataTable<DataRow>();
错误消息@ last row:
ArgumentNullException未处理 - 值不能为null。参数名称:source
答案 0 :(得分:2)
问题是as IEnumerable<DataRow>
演员。如果删除该行,您会看到您的查询选择的是一个匿名类型,其中包含属性KeyID
和Difference
,不一个IEnumerable。 as
运算符会尝试转换IEnumerable<DataRow>
并返回null
,如果没有这样的强制转换。这就是你的空引用异常来自的地方。
要解决此问题,您需要找到一种不同的方法来填充IEnumerable<a'>
中的DataTable(其中a'
是匿名类型)
DataTable difference = new DataTable();
difference.Columns.Add("KeyID", typeof(string));
difference.Columns.Add("Difference", typeof(decimal));
foreach (var result in diff)
difference.Rows.Add(result.KeyID, result.Difference);
答案 1 :(得分:2)
问题是当你这样做时:
select new {...}
您正在创建一个匿名类,而不是DataRow。因此,当你施展as IEnumerable<DataRow>
时,它变为null
如果使用隐式类型变量:
var diff =
(from datarows1 in TestOutput.AsEnumerable()
join datarows2 in ExpectedOutput.AsEnumerable()
on datarows1.Field<String>("external_id") equals datarows2.Field<String>("external_id")
select new
{
KeyId = datarows1.Field<String>("external_id"),
Difference = datarows1.Field<Decimal>("quantity") - datarows2.Field<Decimal>("quantity")
});
这将创建正确类型的差异。
答案 2 :(得分:0)
您在select new
中使用了匿名类型,而不是使用匿名类型,您应该使用某种继承自DataRow
的类型,如当前的表类型:
.....
select new MyDataType
{
external_id= datarows1.Field<String>("external_id"),
quantity = datarows1.Field<Decimal>("quantity")
- datarows2.Field<Decimal>("quantity")
}) .ToList();
DataTable difference = diff.CopyToDataTable<DataRow>();
实际上你的演员表是无效的,它将被转换为null。