0

エンティティフレームワークでグループ化を行っているときに、この問題に遭遇しました。

.Net: 4.5、EF: 5.0、データベース: オラクル

私の問題は、サーバーでグループ化してデータを取得したときでした。グループ化されたデータ (エンティティのリスト) は、グループ化されたすべてのデータに対して最初のレコードを何度も返していましたが、グループ KEY は正しかったです。

レコードごとにグループ化を行わないと、期待どおりに戻りますが、グループ化の要件がいくつかあり、回避策は...ええ、気分が良くなく、コードが機能するはずです...しかし、そうではありません。

xD = 文字列残りは整数/文字列ミックスです。

動作しなかったコードは次のとおりです。

db.ENTITY_NAME
.Where(x =>
       wantedGs.Contains(x.G) &&
       wantedAs.Contains(x.A)
    )
.GroupBy(x => x.D)
.ToList()
.Select(x => x.FirstOrDefault())
.Select(x => new MyEntity
    {
        A = x.A,
        B = x.B,
        C = x.C,
        E = x.E,
        D = x.D,
        F = x.F,
        G = x.G
    })
.ToList();

これが私がやりたいことをなんとかした回避策です:

db.ENTITY_NAME
.Where(x =>
       wantedGs.Contains(x.G) &&
       wantedAs.Contains(x.A)
    )
.Select(x => new
{
    x.A,
    x.B,
    x.C,
    x.D,
    x.E,
    x.F,
    x.G
})
.ToList()
.GroupBy(x => x.D)
.Select(x => x.FirstOrDefault())
.Select(x => new MyEntity
    {
        A = x.A,
        B = x.B,
        C = x.C,
        E = x.E,
        D = x.D,
        F = x.F,
        G = x.G
    })
.ToList();
4

2 に答える 2

0

この種の問題を診断するには、LINQPad が役立つと思います。Oracle テーブルに対してクエリを実行し、 [結果] タブから [ SQL ] タブに切り替えると、最初の例が 1 つの最初の SQLになり、その後に必要な適切なグループ化を実現するのに役立たないselect複数のステートメントが続くことに注意してください。select私にはバグのように見えます。

この問題は Oracle 固有のようです (おそらく特定のクライアント バージョン)。GroupBy複数の SQL もありましたが、Microsoft SQL Express データベースで同様の結果が得られましたselect

GroupByデータベース接続で使用する場合は注意が必要なようです。その時点から LINQ to data を使用しているように、早い段階で評価 (たとえば、リストへの変換) する方が、より迅速かつ正確になる可能性があります。

再現ケースで更新:

まず、Oracle (9i) テーブルの作成と行の挿入:

create table payees (
   name varchar2(10),
   amount number(5));
insert into payees values ('JACK', 150);
insert into payees values ('BARRY', 100);
insert into payees values ('EMMA', 20);
insert into payees values ('FLAVIA', 15);
insert into payees values ('SYLVIA', 300);
commit;

良い LINQ ステートメントと悪い LINQ ステートメント (Oracle 9i クライアントを使用):

var good = Payees.ToList().GroupBy(p => p.Amount / 100);
var bad = Payees.GroupBy(p => p.Amount / 100);

インテリジェントな LINQ to Oracle ドライバーが使用すると予想したクエリの例:

select trunc(amount/100) pay_category, name, amount
from payees
order by pay_category;

PAY_CATEGORY NAME           AMOUNT
------------ ---------- ----------
           0 EMMA               20
           0 FLAVIA             15
           1 JACK              150
           1 BARRY             100
           3 SYLVIA            300

実際の奇妙なクエリ LINQPad が [SQL] タブにレポートするため、有用なグループ化はまったく行われません。

SELECT t0.AMOUNT
FROM GENSYS.PAYEES t0
GROUP BY t0.AMOUNT

SELECT t0.AMOUNT, t0.NAME
FROM GENSYS.PAYEES t0
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0))
-- n0 = [15]

SELECT t0.AMOUNT, t0.NAME
FROM GENSYS.PAYEES t0
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0))
-- n0 = [20]

SELECT t0.AMOUNT, t0.NAME
FROM GENSYS.PAYEES t0
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0))
-- n0 = [100]

SELECT t0.AMOUNT, t0.NAME
FROM GENSYS.PAYEES t0
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0))
-- n0 = [150]

SELECT t0.AMOUNT, t0.NAME
FROM GENSYS.PAYEES t0
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0))
-- n0 = [300]

ただし、LINQ to SQL に期待しすぎているかもしれません。(私の LINQPad は、LINQPad ドライバーが IQ V2.0.7.0 であると報告しています。それが役立つ場合)。

于 2013-12-12T15:43:28.663 に答える
0

これでうまくいかない場合は、問題を示すサンプル データを投稿してください

db.ENTITY_NAME
.Where(x =>
       wantedGs.Contains(x.G) &&
       wantedAs.Contains(x.A)
    )
.GroupBy(x => x.D)
.Select(x => x.FirstOrDefault())
.AsEnumerable()
.Select(x => new MyEntity
    {
        A = x.A,
        B = x.B,
        C = x.C,
        E = x.E,
        D = x.D,
        F = x.F,
        G = x.G
    })
.ToList();
于 2013-02-28T14:26:01.917 に答える