使用List<DataRow>.DefaultIfEmpty()报错,如何获取新DataRow?
问题解决与优化方案
错误原因
你调用Data.DefaultIfEmpty()得到的是可枚举集合(IEnumerable<DataRow>),不是单个DataRow对象,直接强制类型转换必然抛出InvalidCastException。
核心注意点
DataRow不能脱离DataTable独立存在,所有DataRow都必须从对应的DataTable中创建(通过DataTable.NewRow()方法),不能直接实例化。
修正后的代码方案
方案1:创建全新的DataRow(与现有Data同结构)
如果你的需求是生成一条全新的、和Data列表中行结构一致的DataRow,可以用以下代码:
public List<DataRow> Data { get; set; } = new(); private DataRow GetDataRow(COAClassRecord _Record) { DataTable targetTable; // 获取或创建对应的DataTable if (Data.Any()) { // 从现有DataRow中获取关联的DataTable targetTable = Data[0].Table; } else { // 如果Data为空,手动定义DataTable结构(需匹配实际字段类型) targetTable = new DataTable(); targetTable.Columns.Add("Id", typeof(int)); targetTable.Columns.Add("Code", typeof(string)); targetTable.Columns.Add("Title", typeof(string)); } // 创建新的空白DataRow DataRow newRow = targetTable.NewRow(); // 赋值 newRow["Id"] = _Record.ID; newRow["Code"] = _Record.Code; newRow["Title"] = _Record.Title; return newRow; }
方案2:优先复用Data中的行,空则创建新行
如果你的意图是:当Data列表不为空时复用其中的某一行(比如第一行),为空时再创建新行,可以调整为:
public List<DataRow> Data { get; set; } = new(); private DataRow GetDataRow(COAClassRecord _Record) { DataRow targetRow = Data.FirstOrDefault(); if (targetRow == null) { // 空列表时创建DataTable和新行 DataTable table = new DataTable(); table.Columns.Add("Id", typeof(int)); table.Columns.Add("Code", typeof(string)); table.Columns.Add("Title", typeof(string)); targetRow = table.NewRow(); } // 赋值覆盖原有数据 targetRow["Id"] = _Record.ID; targetRow["Code"] = _Record.Code; targetRow["Title"] = _Record.Title; return targetRow; }
关键说明
- 替换
DefaultIfEmpty():要获取单个元素,使用FirstOrDefault()(返回第一个元素或默认值)、SingleOrDefault()这类方法,而不是DefaultIfEmpty()(返回包含默认值的集合)。 - 必须绑定DataTable:所有
DataRow都属于某个DataTable,如果没有现有DataTable,必须先定义列结构,否则赋值时会因找不到对应列报错。
内容的提问来源于stack exchange,提问作者Mohammad Aamir Jahangir
相关产品推荐
相关产品推荐

