【问题标题】:Detect duplicate set of IDs in grouped collection检测分组集合中的重复 ID 集
【发布时间】:2020-02-11 20:58:23
【问题描述】:

我有以下课程:

public class ExistingProposal
{
    public Guid ProposalIdPK { get; set; }
    public int StatusCode { get; set; }
    public List<ExistingProposalElement> GoldenRecordElements { get; } = new List<ExistingProposalElement>();
}

public class ExistingProposalElement
{
    public Guid ProposalElementIdPK { get; set; }
    public Guid ProposalIdFK { get; set; } // foreignkey referencing ExistingProposal.ProposalIdPK
}

此类使用现有提案及其元素进行初始化。提案将具有各种状态代码,例如“已接受”、“已拒绝”等。

在创建新提案和元素时,我需要检查是否已经存在包含与新提案相同元素的提案

让我们假设以下情况:

ExistingProposal    ExistingProposalElement
1                   1
                    2
                    3
2                   5
                    6
                    7

现在需要使用 ID 为 5,6 和 7 的元素创建新提案。我的检查现在需要检测 已经有一个带有这些 ID 的提案。

新的 ProposalElement-ID 包含在一个

List<Guid> newElements

如何检测到已经有一个提案包含与我的列表“newElements”和特定“StatusCode”中包含的相同的 ProposalElement-ID?

我认为它与 Linq “All” 方法或类似方法有关,但我真的坚持使用它,因为我对 Linq 并不是很先进。

任何帮助将不胜感激。

【问题讨论】:

  • 您想要元素的精确匹配吗?例如,如果您有一个新的提案 5,6 和 7,您需要匹配还是应该匹配 5 和 6 还是应该匹配 5,6 和 8?你明白了。
  • 我需要完全匹配...所以如果现有提案和新提案包含完全相同的 ID,我需要匹配。如果我收到 ID 5,6,7 并且已经有一个元素 ID 为 5,6,7 的现有提案,我需要得到一个真实的示例

标签: c# list linq duplicates microsoft-dynamics


【解决方案1】:

这是我设置的用于测试的虚拟类。我设置了您提供的两个示例,然后设置了一个新提案以检查它是否已经存在。

var existingProposal1 = new ExistingProposal
{
    Id = 1,
    GoldenRecordElements = new List<ExistingProposalElement>
    {
        new ExistingProposalElement{ Id = 1 },
        new ExistingProposalElement{ Id = 2 },
        new ExistingProposalElement{ Id = 3 },
    }
};

var existingProposal2 = new ExistingProposal
{
    Id = 2,
    GoldenRecordElements = new List<ExistingProposalElement>
    {
        new ExistingProposalElement{ Id = 4 },
        new ExistingProposalElement{ Id = 5 },
        new ExistingProposalElement{ Id = 6 },
    }
};

List<ExistingProposal> existingProposals = new List<ExistingProposal>
{
    existingProposal1,
    existingProposal2
};

var newElements = new List<int> { 1, 2, 3 };

此代码应该让您知道它是否已经存在。

var exists = existingProposals.Any(x => x.GoldenRecordElements
     .Select(y => y.Id)
     .Intersect(newElements).Count() == x.GoldenRecordElements.Count());

【讨论】:

  • 非常感谢您的回复。但我仍然想念我需要将 List 中持有的 ID 与现有提案进行比较的事实。因此,如果 List 包含 1,2,3 并且任何已经存在的提案都包含完全相同的 Element-ID,我需要得到一个 true 例如。主要目标是避免在现有提案已经包含相同元素的情况下创建提案
  • 这不是我的代码在做什么,只是我在检查一个 int Id 而不是一个 Guid,但它的主体是相同的?
  • 是的,一般来说你是对的,但如上所述,我需要检查列表,因为如果已经存在具有完全相同元素的提案,则不应创建提案
  • 我更改了它,以便它检查 Id 列表?这是否有帮助还是我离基地很远?
  • 这看起来好多了 :) 会尝试提供反馈 :)
【解决方案2】:

我建议使用 SelectMany,因为我对您的理解正确。它比其他解决方案更容易。

var existingItemsWithStatusCode = existingProposals.SelectMany(s => s.GoldenRecordElements,
                    (s, p) => new { s.ProposalIdPK, s.StatusCode, p.ProposalElementIdPK })
                .Where(w => newProposals.SelectMany(s => s.GoldenRecordElements.Select(t => t.ProposalElementIdPK))
                    .Contains(w.ProposalElementIdPK)).Select(s=>new
                {
                    s.ProposalElementIdPK,s.StatusCode
                }).ToList();

var newItems = existingProposals.SelectMany(s => s.GoldenRecordElements,
                    (s, p) => new {s.ProposalIdPK, s.StatusCode, p.ProposalElementIdPK})
                .Where(w => !newProposals.SelectMany(s => s.GoldenRecordElements.Select(t => t.ProposalElementIdPK))
                    .Contains(w.ProposalElementIdPK)).ToList();

【讨论】:

  • 非常感谢。如上所述,我需要对包含所有新(传入)元素 ID 的 List 进行检查。如果在已经存在的提案中找到了这些 ID,则根本不需要创建新的提案。这些建议实际上都只在现有提案中进行检查
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
相关资源
最近更新 更多