如果想要保留一个平面的列列表(即 OP 的 Edit2),并且还想要一个通用的解决方案,它可以与任何 IEnumerable 一起使用,而不需要您列出预期的列集,那么没有直接的方法。
但是,有一种迂回的方法可以解决这个问题,即使用 here 中的 ToDataTable() 方法将查询结果转储到 DataTable 中,然后将 RowNumber 列添加到该表中。
var table = query.ToList().ToDataTable();
table.Columns.Add("RowNum", typeof(int));
int i = 0;
foreach (DataRow row in table.Rows)
row["RowNum"] = ++i;
这可能会导致大型数据集出现性能问题,但也不会非常慢。在我的机器上,大约 6500 行的数据集需要 33 毫秒来处理。
如果您的原始查询返回匿名类型,那么该类型定义将在转换中丢失,因此当您调用 table.AsEnumerable() 时,您将丢失生成的 IEnumerable 的列名的静态类型。换句话说,您不必编写 table.AsEnumerable().First().RowNum 之类的东西,而是必须编写 table.AsEnumerable().First()["RowNum"]
但是,如果您不关心性能并且确实希望恢复静态类型,那么您可以使用 JSON.NET 将 DataTable 转换为 json 字符串,然后根据原始匿名类型转换回列表查询结果。此方法要求原始查询结果中存在占位符 RowNum 字段。
var query = (from currRow in someTable
where currRow.someCategory == someCategoryValue
orderby currRow.createdDate descending
select new { currRow.someCategory, currRow.createdDate, RowNum = -1 }).ToList();
var table = query.ToDataTable();
//Placeholder RowNum column has to already exist in query results
//So not adding a new column, but merely populating it
int i = 0;
foreach (DataRow row in table.Rows)
row["RowNum"] = ++i;
string json = JsonConvert.SerializeObject(table);
var staticallyTypedList = JsonConvert.DeserializeAnonymousType(json, query);
Console.WriteLine(staticallyTypedList.First().RowNum);
这使我的 6500 项数据集的处理时间增加了大约 120 毫秒。
这很疯狂,但它确实有效。