列のフラット リスト (つまり、OP の Edit2) を保持し、予想される列のセットをリストする必要なく、任意の IEnumerable で動作する汎用ソリューションが必要な場合、簡単な方法はありません。
ただし、ここから 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 ミリ秒増加しました。
クレイジーですが、うまくいきます。