Синтаксис SQL «не в» для Entity Framework 4.1 - PullRequest
24 голосов
/ 25 августа 2011

У меня есть простая проблема с синтаксисом Entity Framework для эквивалента «не в» 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(), но ни один из примеров не был достаточно близким.

Ответы [ 4 ]

52 голосов
/ 25 августа 2011

Попробуй ...

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>)

соответственно.

3 голосов
/ 25 августа 2011

Этот требует от вас немного подумать задом наперед.Вместо того, чтобы спрашивать, нет ли значения в каком-либо списке идентификаторов, вы должны спросить, какой список идентификаторов не содержит это значение.Как это

int[] list = new int[] {1,2,3}
Result = (from x in dbo.List where list.Contains(x.id) == false select x);
2 голосов
/ 25 августа 2011

Попробуйте для начала ...

m => !listIDs.Contains(m.ID)
0 голосов
/ 25 августа 2011

Это может быть способ сделать то, что вы хотите:

// 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 не заполняет переменную при построении фильтра / запроса (по крайней мере, по умолчанию). Если вы собираетесь выполнять итерацию для каждой записи, не забывайте вызывать метод ToList () или ToArray (), если только у каждой записи нет 500 МБ или более ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...