在单个方法中使用两个 Linq 查询



如下面的代码所示,API 将命中数据库两次以执行两次 Linq 查询。我不能通过只点击一次数据库来执行下面显示的操作吗?

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

为了向数据库发出一个请求,您可以先仅过滤相关值,然后再次检查查询结果中的特定值:

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()调用将对数据库执行一次查询并返回相关值

开头为

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

可以通过一个小技巧来实现,它按常量分组:

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

并不是说我会像那样推荐它。代码不是不言自明的,对我来说,这似乎是一个过早的优化。

您可以使用

ValueTuple 和 LINQ 的 .聚合() 方法:

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

相关内容

  • 没有找到相关文章

最新更新