web-dev-qa-db-ja.com

Entity Framework 4.1のSQL "not in"構文

Entity Frameworkの「not in」SQLの構文の簡単な問題があります。基本的に、次のSQL構文をEntity Framework構文に変換したいと思います。

_select  ID
from    dbo.List
where   ID not in (list of IDs)
_

これは、単一のレコードを検索するために使用する方法です。

_public static List GetLists(int id)
{
    using (dbInstance db = new dbInstance())
    {
        return db.Lists.Where(m => m.ID == id);
    }
}
_

これは私がこれに使用したい疑似メソッドです:

_public static List<List> GetLists(List<int> listIDs)
{
    using (dbInstance db = new dbInstance())
    {
        return db.Lists.Where(**** What Goes Here ****).ToList();
    }
}
_

Where句の領域に何が入るのか、誰かに教えてもらえますか?私はこれについていくつかのフォーラムを読み、.Contains()または.Any()の使用についての言及を見ましたが、どの例も十分に適合していませんでした。

24
Ian Lopes

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

public static List<List> GetLists(List<int> listIDs)
{
    using (dbInstance db = new dbInstance())
    {
        // Use this one to return List where IS NOT IN the provided listIDs
        return db.Lists.Where(x => !listIDs.Contains(x.ID)).ToList();

        // Or use this one to return List where IS IN the provided listIDs
        return db.Lists.Where(x => listIDs.Contains(x.ID)).ToList();
    }
}

これらは、およそ次のデータベースクエリになります。

SELECT [Extent1].*
FROM [dbo].[List] AS [Extent1]
WHERE  NOT ([Extent1].[ID] IN (<your,list,of,ids>))

または

SELECT [Extent1].*
FROM [dbo].[List] AS [Extent1]
WHERE  [Extent1].[ID] IN (<your,list,of,ids>)

それぞれ。

52
ckittel

これは少し後ろ向きに考える必要があります。値がIDのリストにないかどうかを尋ねる代わりに、IDのリストに値が含まれていないことを尋ねる必要があります。このような

int[] list = new int[] {1,2,3}
Result = (from x in dbo.List where list.Contains(x.id) == false select x);
3
Kyeotic

手始めにこれを試してください...

m => !listIDs.Contains(m.ID)
2
Antony Scott

これはあなたが望むことをする方法かもしれません:

// From the method you provided, with changes...
public static List GetLists(int[] ids) // Could be List<int> or other =)
{
    using (dbInstance db = new dbInstance())
    {
        return db.Lists.Where(m => !ids.Contains(m.ID));
    }
}

ただし、そうすると、一部のシナリオでエラーが発生する可能性があることがわかりました。特に、リストが大きすぎて接続がやや遅い場合に発生します。

このフィルターのチェックする値が少なくなるように、他のすべてを事前に確認することを忘れないでください。

また、フィルター/クエリを作成するとき、Linqは変数を設定しないことも覚えておいてください(少なくともデフォルトでは)。各レコードを反復処理する場合は、各レコードが500MB以上でない限り、前にToList()またはToArray()メソッドを呼び出すことを忘れないでください...

0
Anderson Matos