Использование двух запросов Linq в одном методе - PullRequest
0 голосов
/ 21 января 2019

Как показано в приведенном ниже коде, API дважды попадет в базу данных, чтобы выполнить два запроса Linq. Разве я не могу выполнить действие, показанное ниже, попав в базу данных только один раз?

var IsMailIdAlreadyExist = _Context.UserProfile.Any(e => e.Email == myModelUserProfile.Email);

var IsUserNameAlreadyExist = _Context.UserProfile.Any(x => x.Username == myModelUserProfile.Username);

Ответы [ 4 ]

0 голосов
/ 22 января 2019

Это возможно с небольшим взломом, который группирует по константе:

var presenceData = _Context.UserProfile.GroupBy(x => 0)
    .Select(g => new
    {
        IsMailIdAlreadyExist = g.Any(x => x.Email == myModelUserProfile.Email),
        IsUserNameAlreadyExist = g.Any(x => x.Username == myModelUserProfile.Username),
    }).First();

Группировка дает вам доступ к 1 группе, содержащей все UserProfile с, к которым вы можете обращаться так часто, как вы хотите водин запрос.

Не то, чтобы я рекомендовал это просто так.Код не требует пояснений, и мне кажется, что это преждевременная оптимизация.

0 голосов
/ 21 января 2019

Начните с

var matches = _Context
  .UserProfile
  .Where(e => e.Email == myModelUserProfile.Email)
  .Select(e => false)
  .Take(1)
  .Concat(
    _Context
      .UserProfile
      .Where(x => x.Username == myModelUserProfile.Username)
      .Select(e => true)
      .Take(1)
  ).ToList();

Получается достаточно информации, чтобы различать четыре варианта (без совпадения, совпадения по электронной почте, совпадения имени пользователя и совпадения) с одним запросом, который не возвращает более двух строксамое большее, и не получает неиспользованную информацию.Следовательно, примерно такой маленький запрос может быть.

С этим сделано:

bool isMailIdAlreadyExist = matches.Any(m => !m);
bool isUserNameAlreadyExist = matches.LastOrDefault();
0 голосов
/ 21 января 2019

Вы можете сделать все это в одной строке, используя ValueTuple и LINQ .Aggregate () метод:

(IsMailIdAlreadyExist, IsUserNameAlreadyExist) = _context.UserProfile.Aggregate((Email:false, Username:false), (n, o) => (n.Email || (o.Email == myModelUserProfile.Email ? true : false), n.Username || (o.Username == myModelUserProfile.Username ? true : false)));
0 голосов
/ 21 января 2019

Чтобы сделать один запрос к базе данных, вы можете сначала отфильтровать только релевантные значения, а затем снова проверить наличие определенных значений в результате запроса:

var selection = _Context.UserProfile
    .Where(e => e.Email == myModelUserProfile.Email || e.Username == myModelUserProfile.Username)
    .ToList();

var IsMailIdAlreadyExist = selection.Any(x => x.Email == myModelUserProfile.Email);
var IsUserNameAlreadyExist = selection.Any(x => x.Username == myModelUserProfile.Username);

Вызов .ToList() здесь выполнит запрос к базе данных один раз и вернет соответствующие значения

...