在将列表传递给LINQ时调用单个数据库

本文关键字:调用 单个 数据库 LINQ 列表 | 更新日期: 2023-09-27 18:13:05

我得到一个电子邮件地址数组,对于每个电子邮件地址,我需要返回与该电子邮件地址相关的成员的numTotal和numActive。

传统上,我会从成员表中查询并过滤成员的电子邮件地址是否存在于传入的email数组中。但是,这只会返回电子邮件地址列表,其中包含成员表中存在的电子邮件的计数。相反,我需要记录每个提供的电子邮件地址,而不管成员是否拥有该电子邮件地址。

我的解决方案是遍历电子邮件数组,然后做一个子查询。这是有效的,我能够得到我需要的,但是当我配置调用时,我看到EF正在为每个电子邮件地址/子查询运行单独的查询。

var result = (from email in emailAddresses
              select new EmailAddressStats {
                 Total = membersQueryable.Any(m => m.Email == email),
                 Active = membersQueryable.Any(m => m.Email == email && m.IsActive)
              }).ToList();

所以如果我传递3个电子邮件地址,我看到6个单独的查询(3个电子邮件地址* 2个子查询)。

我已经尝试使用.AsQueryable()使数组可查询,但我仍然得到相同的结果。

理想情况下,我希望EF生成如下内容:

SELECT ([totalSubquery]) AS Total,
       ([activeSubquery]) AS Active
FROM ????
WHERE EXISTS ('email1@domain.com', 'email2@domain.com', 'email3@domain.com' )

注意:我使用实体框架4

在将列表传递给LINQ时调用单个数据库

我没有安装EF4,但你应该能够这样做,只执行一个查询。

List<EmailAddressStats> GetEmailAddressStats(string[] emailAddresses)
{
    var returnList = emailAddresses.Select(e => new EmailAddressStats { Email = e })
                                   .ToList();
    // I don't know what your context is actually called so I'm just calling it MemberDatabaseContext)
    using (var dbContext = new MemberDatabaseContext())
    {
        // Query the database once with a single query to get all of the relevant members
        var membersWithEmailAddress = dbContext.Members.Where(m => emailAddresses.Contains(m.Email))
                                                       .Select(m => new { Email = m.Email, IsActive = m.IsActive })
                                                       .ToList();
        // Update the email stats by analyzing the member info in memory
        foreach (var emailStat in returnList)
        {
            emailStat.Total = membersWithEmailAddress.Count(m => m.Email == emailStat.Email);
            emailStat.Active = membersWithEmailAddress.Count(m => m.Email == emailStat.Email && m.isActive);
        }
    }
    return returnList;
}    

(对不起,这是在流利的语法,而不是查询表达式语法,但我只知道如何做到这在流利的语法)