根据 ID 列表更新对象列表中的 属性

Update Property in List of objects based from a list of ids

两个列表。一个是代表我向其发送电子邮件的一组人的对象。为简洁起见,假设结构是

public class EmailSent
{
    public int Id {get;set;}
    public string Email {get;set;}
    public bool HasResponse {get;set;}
}

我发送的每封电子邮件都有 table 支持(减去 HasResponse 列)。我有另一个 table 存储所有回复。

public class EmailResponse
{
    public int Id {get;set;}
    public string Response {get;set;}
}

我有一个测试目前失败了,我不知道如何让它通过。在生产中,我基本上用 SELECT Id, Email from EmailSent where Id between @MinId and @MaxId 之类的东西查询 EmailSent table 那里没什么好看的。我的测试基本上做了一个 yield return ,它在每个数字之间做了一个 EmailSent ...下一部分是我在那个列表上做一个 select 给我 Id 并进行第二个查询到 EmailResponse。 SELECT Id from EmailResponse WHERE Id in (...generate list of id's) 在我的测试中我写

public IEnumerable<EmailResponse> GetEmailResponses(IEnumerable<long> Ids, int waveId)
{
    foreach (var id in Ids.Take(10))
    {
        yield return new EmailResponse {Id = id};
    }
}

失败的测试是这个

   [Test]
    public void WhenAnEmailGroupIsSelectedSpecificInformationIsShown()
    {
        _viewModel.SelectedEmailGroup = _viewModel.EmailGroups[0];
        _viewModel.Emails.Count.Should().Be(286);
        _viewModel.Emails.Count(x => x.HasMatchingResult).Should().Be(10);
    }

它失败并显示错误消息,预计计数为 10,但发现为 0。我现在所做的是(为清楚起见,将 var 更改为 IEnumerable)

IEnumerable<EmailGroup> emails = _dao.GetEmailsSent(SelectedEmailGroup);
IEnumerable<EmailResponse> results = _dao.GetEmailResponses(emails.Select(x => x.Id), SelectedEmailGroup.WaveId);
IEnumerable<EmailGroup> matches = emails.Join(results, x => x.Id, y => y.Id, (x, y) => x).ToList();
//matches.ForEach(x => x.HasMatchingResult = true); this is the line that probably needs to change
foreach (var email in emails)
{
    Emails.Add(email);
}

我很清楚哪里出了问题,但我不知道如何根据回复轻松更新电子邮件。请帮助:)

最有可能的问题是您在制作 emails IEnumerable 时没有 ToList(),这意味着它会在您的单元测试要求时再次生成.此时 HasMatchingResult 标志将丢失,因此您的测试将失败。解决这个问题很简单 - 只需将 ToList 添加到 emails 的调用中,然后取消注释 ForEach:

IEnumerable<EmailGroup> emails = _dao.GetEmailsSent(SelectedEmailGroup).ToList();

您不需要在那里执行连接:您所要做的就是在 responces:

中选择具有匹配 IdEmailGroup
ISet<int> emailIdsWithResponses = new HashSet<int>(results.Select(r => r.Id));
IEnumerable<EmailGroup> matches = emails.Where(e => emailIdsWithResponses.Contains(e.Id)).ToList();

此时你可以调用你的 ForEach,或者更好的是遍历 "plain" foreach 循环中的项目,设置它们的 HasMatchingResult 标志:

foreach (var e in matches) {
    e.HasMatchingResult = true;
}