2011-01-30 4 views
4

基本的には、オブジェクトのリストを取得し、基準の1つ別のリストには存在しません。ここでは例を示します。
私の2つのクラスがこれに似ています。LINQクエリ:あるリスト内のオブジェクトがキーに基づいて別のリストに存在するかどうかを確認

public class Test 
{ 
    public string name; 
    public string instructor_name; 
    public string course; 
} 

public class Appointment 
{ 
    public string site; 
    public DateTime forWhen; 
    public string testName; 
} 

私はもちろん見て、テストが一覧<予定に存在していないことを確認することで一覧<試験>をソートしたいです>。 SQLでは、次のようなことをします:

SELECT new Group<Test>(c.Key, c) 
FROM tests in testList 
WHERE tests.Course != "Science" 
AND tests.name NOT IN (SELECT testName FROM appotList) 

しかし、私はLINQでこれをどうやって行うのか分かりません。何か案は?

+0

SQLの最初の行を見たいと思うかもしれません...それはSQLではありません:) –

+0

私はこれを認識しますが、私はSQLでそれをやろうとしていません。それは、私がSQLでそれをやっていた場合に使用するフォーマットです。私はそれを書いて、人々が私がLINQで何をしようとしていたのかをよりよく理解できるようにしました。 – legacybass

答えて

4

http://introducinglinq.com/blogs/marcorusso/archive/2008/01/14/the-not-in-clause-in-linq-to-sql.aspx

Ordersテーブルの順序を持​​っていないすべての顧客を返すこのコードを考えてみましょう。これは、その値を返すSQLクエリです。

SELECT * 
FROM [dbo].[Customers] AS [t0] 
WHERE [t0].[CustomerID] NOT IN (
    SELECT [t1].[CustomerID] 
    FROM [dbo].[Orders] AS [t1] 
) 

これは、望ましい結果を得るための高速な方法ではありません(NOT EXISTSを使用するのが好きな方法です。 LINQは、次のコードを記述できるContains拡張メソッドを提供します。クエリをLINQ to SQLはで

NorthwindDataContext dc = new NorthwindDataContext(); 
dc.Log = Console.Out; 
var query = 
    from c in dc.Customers 
    where !(from o in dc.Orders 
      select o.CustomerID) 
      .Contains(c.CustomerID) 
    select c; 
foreach (var c in query) Console.WriteLine(c); 

は、このSQLコードに変換されます。

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], 
     [t0].[ContactTitle], [t0].[Address], [t0].[City], 
     [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax] 
FROM [dbo].[Customers] AS [t0] 
WHERE NOT (EXISTS(
    SELECT NULL AS [EMPTY] 
    FROM [dbo].[Orders] AS [t1] 
    WHERE [t1].[CustomerID] = [t0].[CustomerID] 
    )) 

このアプローチだけでなく、意味的に等価でなく、より高速な実行です。 SET STATISTICS IO ONの結果は次のとおりです。最初の結果は、NOT IN句を使用する手書き問合せです。 2番目の結果は、LINQ to SQL生成クエリです。

+0

質問に間違いがない限り、クライアント側のフィルタリング(SQLでフィルタリングする方法ではなく、LINQ-to-Objects)を行う方法を尋ねているようです。 –

+0

@Adam - LINQクエリはまだ動作するはずです。それ? dc.Customersおよびdc.Ordersの代わりに、彼はオブジェクトのコレクションを使用できます。 –

+0

これは実際に私が探していた情報です。私は3ダースのチュートリアルやドキュメンテーションのサイトを検索したに違いありません。正確に私が必要としたもの。ありがとう! – legacybass

10

クライアント側のフィルタリングについては、LINQ to Objectsを使用するとかなり簡単です。

List<Test> tests = ...; 
List<Appointment> appts = ...; 

var query = tests.Except(
      tests.Join(appts, t => t.name, a => a.testName, (t, a) => t)); 

次が読み少し簡単です::

var query = tests.Where(t => !appts.Any(a => a.testName == t.name)); 

をしかしJoin関数は、ハッシュマッチのテーブルではなく、やって計算しますので、最初のバージョンは、より高速になります。このような何かtestsのすべての要素についてapptsリストの線形検索。

+0

投稿された2番目の回答は私にとって意味がありましたので、私はそれを使用することにしましたが、私はあなたの投稿について興味があります。 Whereメソッド内で複数の選択基準を作成できますか?私は、テストの日付を比較して、テストをまだ取ることができるかどうかを確認し、まだ予定がないことを確認することもできるようにしたかったのです。私は=>演算子を使用することになるとまだ初心者ですので、どのように複数の条件を列挙するのかわかりません。 – legacybass

+0

@legacybass:はい、あなたは 'Where'部分にあなたが望むだけ多くの条件を含めることができます。データベースクエリを作成するのではなく、メモリ内のオブジェクトのリストを調べる方が簡単なので、このバージョンを公開しました。 –

+0

それらはコンマまたはセミコロンで区切られますか? Joinメソッドで複数の条件をどのように使用しますか?それは私が使用方法を学ぶことに最も興味があるでしょう。 – legacybass

関連する問題