Linq用ALL语句删除结果

本文关键字:删除 结果 语句 ALL Linq | 更新日期: 2023-09-27 18:15:58

你好,我正在尝试使用Linq从列表中删除"所有"实体。

问题:我正在搜索数据库中具有某些证书的用户。它会逐行返回....但是我需要检查的是:用户是否持有所有必需的证书。这应该根据我的int数组进行检查。

这是我的数组:[3,5,16],现在我想从列表中删除所有没有所有三个用户的用户。代码中的数组名称必选!

我得到的列表看起来像这样

列。CertificateValue
列。Uid
列。NameOfPerson

基本上在这个例子中,Peter在列表中有三行,在这个例子中,所有的行都需要留在列表中。但是Philip只有2行,因此这两行都应该被删除,因为他没有满足全部搜索条件。

copyOfMandatoryis只是为了不与原始集合混淆并导致期望(集合大小更改)。

foreach (var item in copyOfMandatory)
{
    if (!mandatoryusers.All(i => mandatory.Contains(i.CertificateValue) 
                            || i.Uid == item.Uid))
    {
         mandatoryusers.RemoveAll(i => i.Uid == item.Uid);
    }
}

如果if语句没有像预期的那样工作,RemoveAll就会像魅力一样工作。

这样做不会拿走列表的任何部分,我以&&而不是||但是当它这样做时,它会杀死除了最后遇到的人以外的所有人,只要他/她满足搜索条件。

谁有一个提示如何做到这一点?

Linq用ALL语句删除结果

我会尝试这样做

var uIdToRemove = mandatoryusers.GroupBy(m => m.Uid)
                    .Where(g => mandatory.Except(g.Select(s => s.CertificateValue)).Any())
                    .Select(g => g.Key).ToList();
mandatoryusers.RemoveAll(x => uidToRemove.Contains(x.Uid));

您的All调用不够细粒度:它试图确保所有条目在任何时候都存在…并不是每个USER都存在。

尝试将每个条目转换为字典:

var dict = new Dictionary<int, List<ItemType>>();
foreach (var mandatoryItem in mandatoryItems)
{
    List<ItemType> itemTypeValue = null;
    if (!dict.TryGetValue(mandatoryItem.Uid, out itemTypeValue)
    {
        itemTypeValue = new List<ItemType>();
        dict.Add(mandatoryItem.Uid, itemTypeValue);
    }
    itemTypeValue.Add(mandatoryItem);
}

现在您在Uid键处拥有了所有ItemType。从这里开始,使用LINQ:

mandatoryusers = mandatoryusers.Where(i => dict[i.Uid].All(x => mandatory.Contains(x.CertificateValue));

您的if All条件已关闭。

if (!mandatoryusers.All(i => mandatory.Contains(i.CertificateValue) 
                        || i.Uid == item.Uid))
{
     mandatoryusers.RemoveAll(i => i.Uid == item.Uid);
}

需要使用&&而不是||,您应该调用Any()而不是All()

if (!mandatoryusers.Any(i => mandatory.Contains(i.CertificateValue) 
                            && i.Uid == item.Uid))
{
    mandatoryusers.RemoveAll(i => i.Uid == item.Uid);
}
希望我正确理解了你的逻辑和问题。

您的if语句不正确(如您所述)-它试图检查是否所有项目都包含mandatory 中用户id为当前项目的id证书。您应该做的是首先通过userid 进行过滤,然后检查证书。但我不会这么做。我将按用户对结果进行分组,然后检查证书

var usersWithAllCertificates = mandatoryUsers.GroupBy(mu => mu.Uid)
             //Select the ones that have all 3 certificates
             .Where(g => g.Select(u => u.CertificateValue)
                 .Intersect(mandatory).Count() == 3)
             .Select(g => g.ToList());

Intersect操作符将两个列表合并,结果将是两个列表中相同的项。因此,如果用户拥有所有3个证书(3,5和16),相交的结果将是3项。usersWithAllCertificates对象将包含所需的所有用户。这是显式地选择您想要的值,而不是删除您不想要的值,我认为这是一种更好的方法。注意,这假设每个用户只在列表中出现一次(即只有3个证书)