de-vraag
  • 質問
  • タグ
  • ユーザー
通知:
報酬:
登録
登録すると、質問に対する返答やコメントが通知されます。
ログイン
すでにアカウントをお持ちの方は、ログインして新しい通知を確認してください。
追加された質問、回答、コメントには報酬があります。
さらに
ソース
編集
 Mike
Mike
質問

LINQ-to-entities generic ==回避策

私は以下のLINQ-to-entitiesクエリを持っています

IQueryable> GetFirstOperationsForEveryId
    (IQueryable> ItemHistory)
{
    var q = (from h in ItemHistory
             where h.OperationId ==
                (from h1 in ItemHistory
                 where h1.GenericId == h.GenericId
                 select h1.OperationId).Min()
             select h);
    return q;
}

ItemHistory is a generic query. It can be obtained in the following way

var history1 = MyEntitiySet1.Select(obj =>
    new History{ obj.OperationId, GenericId = obj.LongId });
var history2 = AnotherEntitiySet.Select(obj =>
    new History{ obj.OperationId, GenericId = obj.StringId });

In the end of all I want a generic query being able to work with any entity collection convertible to History.

問題は、内部クエリのGenericId比較のためにコードがコンパイルされないということです(オペレータ '=='は 'T'および 'T'タイプのオペランドに適用できません)。

==を h1.GenericId.Equals(h.GenericId)に変更すると、次の NotSupportedException が表示されます。

タイプ 'System.Int64'をタイプして 'System.Object'にキャストすることができません。エンティティへのLINQは、エンティティデータモデルプリミティブ型のキャストのみをサポートします。

サブクエリの代わりにグループ化を行い、結果に参加しようとしました。

IQueryable> GetFirstOperationsForEveryId
    (IQueryable> ItemHistory)
{
    var grouped = (from h1 in ItemHistory
                   group h1 by h1.GenericId into tt
                   select new
                   {
                        GenericId = tt.Key,
                        OperationId = tt.Min(ttt => ttt.OperationId)
                   });

    var q = (from h in ItemHistory
             join g in grouped
                on new { h.OperationId, h.GenericId }
                equals new { g.OperationId, g.GenericId }
             select h);
    return q;
}

GenericIdは equals キーワードと比較され、動作しますが、実際のデータを持つクエリは遅すぎます(専用のpostgresqlサーバーで11時間実行されています)。

外側のwhereステートメントのための完全な式を構築するオプションがあります。しかし、このコードは長すぎて不明瞭です。

LINQ-to-entitiesのジェネリックとの等価比較の簡単な回避策はありますか?

2 2011-10-27T13:44:55+00:00 4
 Mike
Mike
編集された質問 28日 10月 2011 в 6:41
プログラミング
c#
entity-framework
linq-to-entities
entity-framework-4
MerickOWA
27日 10月 2011 в 3:12
2011-10-27T15:12:25+00:00
さらに
ソース
編集
#56789431

これを試してみてください。余分なクエリ/結合なしであなたが望むものを達成しなければならないと思います

IQueryable> GetFirstOperationsForEveryId
    (IQueryable> ItemHistory)
{
  var q = from h in ItemHistory
          group h by h.GenericId into tt
          let first = (from t in tt
                        orderby t.GenericId
                        select t).FirstOrDefault()
          select first;

  return q;
}
1
0
Yorak Hunt
27日 10月 2011 в 1:47
2011-10-27T13:47:29+00:00
さらに
ソース
編集
#56789430
IQueryable> GetFirstOperationsForEveryId
(IQueryable> ItemHistory)
{
var grouped = (from h1 in ItemHistory
               group t by h1.GenericId into tt
               select new
               {
                    GenericId = tt.Key,
                    OperationId = tt.Min(ttt => ttt.OperationId)
               });

var q = (from h in ItemHistory
         join g in grouped
            on new { h.OperationId, h.GenericId }
            equals new { g.OperationId, g.GenericId }
         select h);
return q;
}
0
0
Wouter de Kort
28日 10月 2011 в 6:52
2011-10-28T06:52:47+00:00
さらに
ソース
編集
#56789432

また、GenericIdとOperationIdプロパティを実装するIItemHistoryインタフェースのTにジェネリック制約を設定することもできます。

0
0
Mike
28日 10月 2011 в 11:16
2011-10-28T11:16:04+00:00
さらに
ソース
編集
#56789433

私の質問にはすでに解決策が含まれています。 group + joinを使用する2番目の方法は、テーブルが適切にインデックス登録されている場合うまく動作します。データベース表から370k行を検索するのに3.28秒かかります。実際、ジェネリックでない変形では、最初のクエリはpostgresqlでは2番目のクエリより遅くなります。 26.68秒対4.75。

0
0
質問の追加
カテゴリ
すべて
技術情報
文化・レクリエーション
生活・芸術
科学
プロフェッショナル
事業内容
ユーザー
すべて
新しい
人気
1
Roxana Elizabeth CASTILLO Avalos
登録済み 15時間前
2
Hideo Nakagawa
登録済み 1日前
3
Sergiy Tytarenko
登録済み 3日前
4
shoxrux azadov
登録済み 5日前
5
Koreets Koreytsev
登録済み 1週間前
© de-vraag :年
ソース
stackoverflow.com
ライセンス cc by-sa 3.0 帰属