2011-08-01 26 views
4

私にはDbSetオブジェクトがありますDbSet<ShippingInformation> ShippingInformations; ShippingInformationにはequals演算子もオーバーライドしました。オブジェクトがDbsetに存在するかどうかを確認

既存のオブジェクトがあるかどうかを調べるには、の両方のオブジェクトxと等しいセットShippingInformationsのyを見つけてください。

は、これまで私が試してみました:

storeDB.ShippingInformations.Contains(shippingInformation); 

しかし、唯一のプリミティブ型のために働くことを。

答えて

7

残念ながら、Equals実装をEFへのクエリで使用することはできません。コードを逆コンパイルして、どのように完了したかを確認できないためです。多くがある場合

bool exists = storeDB.ShippingInformations 
    .Any(info => 
      info.CustomerID == other.CustomerID 
      && info.CountryID == other.CountryID 
     ); 

(私はアイデアを表示するフィールドを作った、otherは、あなたが探しているShippingInformationです。)

:あなたは、述語式でAnyメソッドを使用して問題ないはずですあなたはこの式を再利用したい場所は、あなたが式を結合するためにLinqKitを使用する場合があります:

private static Expression<Func<ShippingInformation, ShippingInformation, bool>> 
    isEqualExpr = 
     (info, other) => 
      info.CustomerID == other.CustomerID 
      && info.CountryID == other.CountryID; 


// somewhere down this class 

var expr = isEqualExpr; // reference the expression locally (required for LinqKit) 
bool exists = storeDB.ShippingInformations 
        .Any(x => expr.Invoke(x, other)); // "injects" equality expression 

このようなコードは、データ層に配置する必要があります。

上記のコードが機能するかどうかはわかりません。 EFではクエリ式で「他の」オブジェクトを使用できないことがあります。これが当てはまる場合(私に教えてください)、比較のためにすべてのプリミティブ型の値を受け入れるように式を修正する必要があります(この例ではExpression<Func<ShippingInformation, int, int, bool>>になります)。

+0

もし私が比較する10のフィールドを持っているなら、1つの式の中にすべてを入れるのではなく、これを行うもっと純粋な方法がありますか? – Seth

+0

これは複数の場所で使用されますか?なぜなら、そうでなければ、1つのクエリだけがきちんとしているからです(私は思う)。静的フィールドとして宣言して[事前にコンパイルする]ことができます(http://msdn.microsoft.com/en-us/library/bb399335.aspx)。これにより、パフォーマンスがさらに向上します。 –

+0

おそらく複数の場所があります。 「静的なフィールドとして宣言する」とはどういう意味ですか?静的メソッドとして比較を行い、それを指すメソッドを宣言することを意味しますか? – Seth

1
bool ifExists = storeDB.ShippingInformations.Any(shi=>shi.Id == objectYouWantToCompareTo.Id); 

これは、equals演算子をオーバーライドする場合にも有効です。

bool ifExists = storeDB.ShippingInformations.Any(shi=>shi == objectYouWantToCompareTo); 
+0

オブジェクトIDの比較だけではありませんか? – Seth

+1

あなたは何かを比較することができますが、Idsは例です。 –

+0

2番目の例は、エンティティフレームワークがどのように完了したかを見るために、 'Equals'実装を逆コンパイルしなければならないので** **動作しません(もちろんそうではありません)。また、ここで 'Equals'を呼び出すことさえありません(' == 'はオーバーライドされない限り、デフォルトで参照を比較します)。 –

1

これを試してみてください。

storeDB.ShippingInformations.ToList().Contains(shippingInformation);

は、あなたはまた、あなたが探しているものを手に入れるIEqualityComparerを実装する必要があります。

+0

これはデータベースから 'ShippingInformations'テーブル全体を持ち出すでしょう。 –

+0

また、 'IEqualityComparer'を実装すると、Entity Frameworkのクエリにはうまくいかないでしょう(実際には、テーブル全体をメモリにロードしてからLINQをオブジェクトにロードするつもりはないと仮定します)。 –

+0

@Danご意見ありがとうございます。 – Seth