0

Как обработать подзапрос IN с помощью LINQ to SQL?

7

Я немного застрял с этой задачей. В общем, я хочу сделать нечто подобное следующему SQL-запросу, используя LINQ to SQL:

SELECT f.* 
FROM Foo f
WHERE f.FooId IN (
    SELECT fb.FooId
    FROM FooBar fb
    WHERE fb.BarId = 1000
)

Не могли бы вы помочь мне с реализацией этого запроса в LINQ to SQL? Буду очень признателен за любую помощь!

5 ответ(ов)

0

Общий способ реализации IN в LINQ to SQL

var q = from t1 in table1
        let t2s = from t2 in table2
                  where <Условия для table2>
                  select t2.KeyField
        where t2s.Contains(t1.KeyField)
        select t1;

В этом примере мы создаем новый запрос, где выбираем записи из table1, аналогично использованию оператора IN. Мы определяем вложенный запрос t2s, который выбирает KeyField из table2 на основании заданных условий. Затем мы отфильтровываем записи t1, проверяя, содержится ли их KeyField в результатах вложенного запроса t2s.

Общий способ реализации EXISTS в LINQ to SQL

var q = from t1 in table1
        let t2s = from t2 in table2
                  where <Условия для table2>
                  select t2.KeyField
        where t2s.Any(t2Key => t2Key == t1.KeyField)
        select t1;

В этом варианте мы используем метод Any для реализации логики, эквивалентной оператору EXISTS. Вложенный запрос t2s снова выбирает ключевые поля из table2, но теперь мы проверяем, существует ли хотя бы одно значение из t2s, которое соответствует KeyField из table1. Таким образом, результат будет включать все записи из table1, для которых выполняются условия существования в table2.

0

Ваш запрос на языке LINQ можно переписать на русский так:

from f in Foo
    where f.FooID ==
        (
            from fb in FooBar
            where fb.BarID == 1000
            select fb.FooID
        )
    select f;

На самом деле, данный запрос использует подзапрос для выбора FooID из таблицы FooBar по условию BarID == 1000. Затем выбираются только те элементы из Foo, у которых совпадает FooID с результатами подзапроса.

Однако, обратите внимание, что такой запрос может вернуть ошибку, если подзапрос вернет несколько значений. Если ваше намерение — получить все записи из Foo, которые имеют FooID, соответствующие FooID из FooBar, добавьте оператор Contains в условие where. Например:

from f in Foo
    where (from fb in FooBar
            where fb.BarID == 1000
            select fb.FooID).Contains(f.FooID)
    select f;

Таким образом, вы получите все подходящие записи из Foo, основываясь на всех FooID, которые соответствуют условию из FooBar.

0

Пожалуйста, попробуйте использовать два отдельных шага:

// Сначала создаем словарь (Dictionary) или коллекцию (Set)
var fids = (from fb in FooBar
            where fb.BarID == 1000
            select new { fooID = fb.FooID, barID = fb.BarID })
            .ToDictionary(x => x.fooID, x => x.barID);

// Затем выполняем выборку из Foo, используя полученный словарь
var result = from f in Foo
             where fids.ContainsKey(f.FooId)
             select f;

Обратите внимание, что в первом запросе вместо = должен использоваться оператор == для сравнения. Кроме того, в следующем запросе правильный метод для проверки существования ключа в словаре — это ContainsKey.

0

Попробуйте изменить ваш запрос LINQ следующим образом:

var fooids = from fb in foobar where fb.BarId == 1000 select fb.fooID;
var ff = from f in foo where fooids.Contains(f.FooID) select f;

В первой строке используется оператор сравнения == вместо = для фильтрации элементов по BarId. Во второй строке вы можете использовать метод Contains, чтобы проверить, содержится ли FooID в коллекции fooids. Это позволит вам получить все элементы из foo, у которых FooID присутствует в fooids.

0

Ваш код содержит несколько ошибок и не совсем корректно написан. Если вы хотите отфильтровать элементы из коллекции Foo на основе наличия связанных элементов в FooBar, то правильный подход будет выглядеть следующим образом:

var foos = Foo.Where(f => FooBar
    .Where(fb => fb.BarId == 1000)
    .Select(fb => fb.FooId)
    .Contains(f.FooId));

Однако, если вы хотите сделать это более эффективно, возможно, вам стоит использовать метод Any, который может улучшить читаемость и производительность. Вот как это можно сделать:

var foos = Foo.Where(f => FooBar.Any(fb => fb.BarId == 1000 && fb.FooId == f.FooId));

Этот вариант будет искать, существуют ли элементы в FooBar, соответствующие условиям, для каждого элемента в Foo. Надеюсь, это поможет решить вашу задачу!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь