#linq
#linq
Вопрос:
Как бы я сделал следующее в LINQ?
select fkUniqueID
from tblUserRights
where fkUniqueID =
(select PkUserID
from Users
where UserID = 'mike')
Ответ №1:
Я предполагаю, что вы используете LINQ to SQL или что-то подобное.
В идеале, с объединением:
var query = from user in db.Users
where user.UserID == "mike"
join userRight in db.UserRights
on user.PkUiserID equals userRight.FkUniqueID
select userRight;
В качестве альтернативы, если вы действительно хотите использовать подзапрос:
var mikeIDs = from user in db.Users
where user.UserID == "mike"
select user.PkUserID;
var query = from userRight in db.UserRights
where mikeIDs.Contains(userRight.fkUniqueID)
select userRight;
(Обратите внимание, что LINQ является ленивым, поэтому это фактически не приведет к выполнению SQL-запроса для первой части.)
Конечно, если вы настроили свои связи, вы можете просто использовать:
var rights = db.Users.Single(u => u.UserID == "mike").UserRights;
… это сработает, если такого пользователя не будет, и это, вероятно, вызовет два запроса к БД.
Комментарии:
1. Спасибо, но почему все же лучше использовать соединение?
2. @user517406: Это понятнее для чтения, ИМО. Для этого и существуют объединения.
Ответ №2:
Что-то вроде этого псевдо-LINQ должно сработать (это практически перевод проблемы)
var uniqueIDs = from userRight in tblUserRights
where fkUniqueID = (from user in Users
where user.UserID = 'mike'
select user.pkUserID).First()
select userRight.fkUniqueID
В SQL нам не нужно использовать ничего подобного First()
конструкции ( Top 1
это был бы эквивалент SQL), потому что SQL попытается работать с нами, работая корректно, если есть только одна запись (или вообще никаких записей), и выдавая описательную ошибку, если есть две или более записей.
В C # это было бы переведено в ошибку времени компиляции, поскольку мы сравниваем с a T
, а запрос возвращает a IEnumerable<T>
.
First()
явно возвращает первое значение T в коллекции или выдает ошибку, если в результате отсутствуют элементы.