Улучшение запроса LINQ

Мне трудно получить синтаксис 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"? Я думаю, что у меня все свойства навигации настроены, но я не уверен, как их правильно использовать или я мог бы улучшить их, изменив их.

Спасибо за чтение

7
задан abatishchev 24 August 2010 в 13:44
поделиться

4 ответа

Используйте объединения, чтобы переписать все как один чистый запрос. Если я правильно прочитал ваши запросы, это должно дать вам правильный результат:

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

8
ответ дан 6 December 2019 в 15:16
поделиться

Вы должны использовать 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);
2
ответ дан 6 December 2019 в 15:16
поделиться

Обратите внимание, что если в вашей базе данных установлено правильное отношение внешнего ключа, 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 (или вызывать исключение).

3
ответ дан 6 December 2019 в 15:16
поделиться

Поскольку вы имеют свойства навигации, с тем же успехом можно использовать их:

Pin pin =
(
  from u in context.Users
  where u.email == email
  from ptu in u.pintousers
  let p = ptu.pin
  select p
).Single();
1
ответ дан 6 December 2019 в 15:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: