Как обработать подзапрос IN с помощью LINQ to SQL?
Я немного застрял с этой задачей. В общем, я хочу сделать нечто подобное следующему 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 ответ(ов)
Общий способ реализации 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.
Ваш запрос на языке 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.
Пожалуйста, попробуйте использовать два отдельных шага:
// Сначала создаем словарь (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.
Попробуйте изменить ваш запрос 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.
Ваш код содержит несколько ошибок и не совсем корректно написан. Если вы хотите отфильтровать элементы из коллекции 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. Надеюсь, это поможет решить вашу задачу!
Обновление данных в одной таблице из другой на основе совпадения ID
Возможно ли задать условия в Count()?
with(nolock) или (nolock) - есть ли разница?
Выполнение SQL из файла в SQLAlchemy
Параметризованные запросы с условиями LIKE и IN