0

私の問題は、Whereステートメントが Entity Framework で正しく機能しないことです。

データベース内の 1 つの行を定義するプロパティを持つクラスがintあります。longこれらのプロパティを呼び出しましょうId&Parent

public class Update
{
    public long Id { get; set; }
    public int Parent { get; set; }
}

次に、それらの更新のリストがあり、各データベース行がリスト内の更新 (両方のプロパティ) と一致する必要があります。

私が試したことは、これらの更新を匿名型に変換し、完全に一致する行のみを見つけようとすることです: int と long の両方が同じです。

// anon type
var mapping = updates.Select(o => new { id = o.Id, parent = o.Parent}).ToList();
var results = from fa in Uvw_MyTable 
              // PROBLEMATIC WHERE
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

しかし、残念ながら、私は常にエラーを受け取ります:タイプ「匿名タイプ」の定数値を作成できません。このコンテキストでは、プリミティブ型 (Int32、String、および Guid など) のみがサポートされます。

私もAnyこのように使用しようとしました:

where mapping.Any(a => fa.Id == a.id && fa.Parent == a.parent)

しかし、同じエラーが発生します。オブジェクトのリストを使用しても同じことが起こりUpdateます。タイプ 'xxx.Update' の定数値を作成できません。このコンテキストでは、プリミティブ型 (Int32、String、および Guid など) のみがサポートされます。

この問題を解決する方法はありますか?

アップデート

このまったく同じクエリは、LINQPad 4 で非常にうまく機能します。

更新 2

問題はこの質問に関連していますか?

アップデート 3

Maarten が指摘したように、この問題には、異なるアプローチを使用して同じ結果を再現するソリューションが必要です。

4

3 に答える 3

1

あなたのコード/質問を正しく理解しているかどうかはわかりませんが、次のようなものがうまくいくように思えます:

var results = from fa in Uvw_MyTable 
                    where updates.Any(u => u.Id fa.Id && u.Parent = fa.Parent)
                    select fa; 

での望ましい動作については明確ではありませんOtherTableが、上記の linq 式の一般的な形式は、使用しているものよりもはるかに効率的です。

重要な点は、複数のフィールドを比較するために匿名型を作成する必要がないということです。したがって、最初の選択 (にmapping) は冗長です。

于 2012-08-08T10:20:42.347 に答える
1

コードで実際に 2 つのクエリを実行しています。

最初のクエリは次のとおりです。

var mapping = updates.Select(o => new { id = o.Id, parent = o.Parent}).ToList();

2番目のクエリは次のとおりです(わかりました、クエリは繰り返されないため、技術的にはクエリはここではまだ実行されていません-ニッチピッキング):

var results = from fa in Uvw_MyTable 
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

ToList() メソッドを使用しているため、最初のクエリは単一のステートメントで定義および実行されます。これは IQueryable ではなくオブジェクトのリストになっているため、EF はこれを SQL に変換できません。IQueryable のままにしておく必要があります。次のように変更すると、動作するはずです。

var mapping = updates
    .Select(o => new { id = o.Id, parent = o.Parent}); // NOT ToList() !!
var results = from fa in Uvw_MyTable 
              where mapping.Contains(new { id = fa.Id, parent = fa.Parent })
              select new { fa };

EF が与えるエラーを説明するには、EF は IQueryable を SQL に変換するか、プリミティブ型 (int、string など) をパラメーターに変換することしかできません。EF は、意味のある方法でオブジェクトの値をデータベースに転送する方法がないため、オブジェクトを SQL に変換できません。


アップデート:

最初のクエリ (今見た) はまったくクエリではなく、そのソースは update という変数です。これがメモリ内のオブジェクトのリストである場合、このクエリはそのように変換できず、クエリを再設計する必要があります (たとえば、Uvw_MyTable の読み込みはメモリです)。「更新」が(同じコンテキストからの)IQueryableである場合、上記の私の答えが機能するはずです。

于 2012-08-08T11:10:09.937 に答える
0

エンティティ フレームワークまたは Linq to sql では、linq クエリは最終的に sql クエリに変換されます。sql に変換できない型またはクラスを使用しているため、linq クエリを sql クエリに変換できません。

于 2012-08-08T10:58:51.067 に答える