31

以下のクエリを変更して、行番号の列(つまり、結果の1ベースのインデックス)を含めるにはどうすればよいですか?

var myResult = from currRow in someTable
               where currRow.someCategory == someCategoryValue
               orderby currRow.createdDate descending
               select currRow;

編集1:私は結果がそうで{idx, col1, col2...col-n}はないことを探してい{idx, row}ます。

EDIT2:行番号は、テーブル行ではなく結果行に対応している必要があります。

EDIT3:私はDataBindこれらの結果をGridView。私の目標は、行番号列をに追加することでしたGridView。おそらく、別のアプローチの方が良いでしょう。

4

9 に答える 9

42

Enumerable.Selectインデックス付きのオーバーロードを持つメソッド構文を使用します。

var myResult = someTable.Select((r, i) => new { Row = r, Index = i })
    .Where(x => x.Row.someCategory == someCategoryValue)
    .OrderByDescending(x => x.Row.createdDate);

でフィルタリングする前にインデックスを選択するため、このアプローチでは、フィルタリングされた結果ではなく、テーブル内の行の元のインデックスが必要であると想定していることに注意してくださいWhere

編集: {idx、行} ではなく {idx、col1、col2...col-n} になる結果を探しています。行番号は、テーブルの行ではなく、結果の行に対応する必要があります。

次に、必要なすべての列を含む匿名型を選択します。

var myResult = someTable.Where(r => r.someCategory == someCategoryValue)
        .OrderByDescending(r => r.createdDate)
        .Select((r, i) => new { idx = i, col1 = r.col1, col2 = r.col2, ...col-n = r.ColN });
于 2013-02-19T15:03:42.403 に答える
6

Select次の方法を使用します。

要素のインデックスを組み込むことにより、シーケンスの各要素を新しい形式に射影します。

例:

var myResult = someTable.Where(currRow => currRow.someCategory == someCategoryValue)
                        .OrderByDescending(currRow => currRow.createdDate)
                        .Select((currRow, index) => new {Row = currRow, Index = index + 1});

あなたの編集に応じて:

結果としてa が必要な場合はDataTable、単に a を使用して非 Linq の方法に進み、DataView後で列を追加することができます。

someTable.DefaultView.RowFilter = String.Format("someCategory = '{0}'", someCategoryValue);
someTable.DefaultView.Sort = "createdDate";
var resultTable = someTable.DefaultView.ToTable();
resultTable.Columns.Add("Number", typeof(int));
int i = 0;
foreach (DataRow row in resultTable.Rows)
    row["Number"] = ++i;
于 2013-02-19T15:02:28.160 に答える
3

楽しみのためにSelect、2 つの引数を使用する代わりの方法を次に示します。

var resultsWithIndexes = myResult.Zip(Enumerable.Range(1, int.MaxValue - 1),
                                      (o, i) => new { Index = i, Result = o });
于 2013-02-19T15:07:13.493 に答える
3

どうですか?

int i;
var myResult = from currRow in someTable
           where currRow.someCategory == someCategoryValue
           orderby currRow.createdDate descending
           select new {Record = i++, currRow};
于 2013-02-19T15:04:15.417 に答える
2

あなたによると、編集1.いいえ、 Linqはテーブルをそのまま返すことはできません。各列を構築できますが、マップされたエンティティの機能は失われます。

これは以前に何度も尋ねられました: Linq結果にインデックスフィールドを追加するにはどうすればよいですか

于 2013-02-19T15:24:56.357 に答える
1

列のフラット リスト (つまり、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 ミリ秒増加しました。

クレイジーですが、うまくいきます。

于 2016-07-08T00:07:53.033 に答える
0
int Lc = 1;

var Lst = LstItemGrid.GroupBy(item => item.CategoryName)
    .Select(group => new { CategoryName = group.Key, Items = group.ToList() ,RowIndex= Lc++ })
    .ToList();
于 2020-04-12T06:29:06.887 に答える
0

私はパーティーに遅れていることを知っていますが、私にとって何がうまくいったかを示したかった.

オブジェクトのリストがあり、オブジェクトには「行番号」の整数プロパティがあります...またはこの場合は「シーケンス番号」です。これは、そのフィールドに入力するために私がしたことです:

myListOfObjects = myListOfObjects.Select((o, i) => { o.SequenceNumber = i; return o; }).ToList();

これが機能するのを見て驚きました。

于 2016-12-22T20:09:11.253 に答える