Мне трудно получить синтаксис LINQ. Как мне лучше выполнить эту команду?
var user = (from u in context.users
where u.email.Equals(email)
select u).Single();
var pinToUser = (from ptu in context.pintousers
where ptu.user_id.Equals(user.id)
select ptu).Single();
var pin = (from p in context.pins
where p.idpin.Equals(pinToUser.pin_idpin)
select p).Single();
return pin;
Как видите, есть пользователь таблицы, пинтусер таблицы и таблица. штырь. Pintouser ссылается на пользователя и пин-код. Можно ли написать что-то короткое, как "user.pintouser.pin"? Я думаю, что у меня все свойства навигации настроены, но я не уверен, как их правильно использовать или я мог бы улучшить их, изменив их.
Спасибо за чтение
Используйте объединения, чтобы переписать все как один чистый запрос. Если я правильно прочитал ваши запросы, это должно дать вам правильный результат:
var pin = (from u in context.users
join ptu in context.pintousers on u.id equals ptu.user_id
join p in context.pins on ptu.pin_idpin equals p.idpin
where u.email == email
select p).Single();
Однако имейте в виду, что если этот запрос вернет что-либо, кроме одного результата, ваш код выдаст исключение.
Если вы хотите обработать возможность получения одной или ни одной строки, вам следует использовать SingleOrDefault ()
.
Если вы хотите обработать возможность получения любого количества строк, вам действительно следует использовать FirstOrDefault ()
.
Вы должны использовать join
, как указывает @JustinNiessner, но это еще один способ написать свой запрос.
var user = context.users.Single(u => u.email == email);
var pinToUser = context.pintousers.Single(ptu => ptu.user_id == user.id);
var pin = context.pins.Single(p => p.idpin == pinToUser.pin_idpid);
Обратите внимание, что если в вашей базе данных установлено правильное отношение внешнего ключа, Linq-to-Sql должен автоматически иметь соединения для вас:
var pin = (from u in context.users
where u.email == email
select u.pintouser.pin).Single();
, что означает, что вы можете уменьшить это до:
var pin = context.users.Where(u=>u.email == email)
.Select(u=>u.pintouser.pin)
.Single();
(ПРИМЕЧАНИЕ ОБ ОБНОВЛЕНИИ: я изначально предлагал следующее, которое намного короче, но я считаю, что это вызовет два обращения к базе данных)
var pin = context.users.Single(u=>u.email == email).Single().pintouser.pin;
Теперь .pintouser.pin
- это безопасно, потому что Single ()
всегда будет возвращать объект user
(или вызывать исключение).
Поскольку вы имеют свойства навигации, с тем же успехом можно использовать их:
Pin pin =
(
from u in context.Users
where u.email == email
from ptu in u.pintousers
let p = ptu.pin
select p
).Single();