Linq:正在将1个子集合与(聚合)子集合进行比较

本文关键字:子集合 聚合 比较 1个 Linq | 更新日期: 2023-09-27 18:21:35

我有一个Linq问题:(DotNet Framework 4.0)

我有以下课程:

public class Employee
{
    public Guid? EmployeeUUID { get; set; }
    public string SSN { get; set; }
}
public class JobTitle
{
    public Guid? JobTitleSurrogateKey { get; set; }
    public string JobTitleName { get; set; }
}

public class EmployeeToJobTitleMatchLink
{
    public EmployeeToJobTitleMatchLink()
    {
        this.TheJobTitle = new JobTitle() { JobTitleSurrogateKey = Guid.NewGuid(), JobTitleName = "SomeJobTitle:" + Guid.NewGuid().ToString("N") };
    }
    public Guid LinkSurrogateKey { get; set; }
    /* Related Objects */
    public Employee TheEmployee { get; set; }
    public JobTitle TheJobTitle { get; set; }
}

public class Organization
{
    public Organization()
    {
        this.Links = new List<EmployeeToJobTitleMatchLink>();
    }
     public int OrganizationSurrogateKey { get; set; }
    public ICollection<EmployeeToJobTitleMatchLink> Links { get; set; }
}

在下面的代码中,我可以比较2个子集合,并获得所需的结果(在"matches1"中)。在这里,我使用"SSN"字符串属性来比较并查找重叠。而Console.Write for matches1正如我所期望的那样工作。

我不知道如何将第一个子集合(org10)与中的所有子集合(allOtherOrgsExceptOrg10(这些组织的所有组织和所有链接)进行比较

注释掉的代码显示了我正在尝试做的事情,这是我今天许多失败尝试中的一个。

但基本上,match2将填充所有SSN重叠。。。但是将org10与allOtherOrgsExceptOrg10、它们的所有"链接"以及它们的Employee.SSN进行比较。org10与带有"AAA"的org20重叠,因此match2将包含"AAA"。并且org10与具有"BBB"的org30重叠,所以匹配2将包含"BBB"。

            Organization org10 = new Organization();
            org10.OrganizationSurrogateKey = 10;
            Employee e11 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
            EmployeeToJobTitleMatchLink link11 = new EmployeeToJobTitleMatchLink();
            link11.TheEmployee = e11;
            org10.Links.Add(link11);
            Employee e12 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
            EmployeeToJobTitleMatchLink link12 = new EmployeeToJobTitleMatchLink();
            link12.TheEmployee = e12;
            org10.Links.Add(link12);

            Organization org20 = new Organization();
            org20.OrganizationSurrogateKey = 20;
            Employee e21 = new Employee() { SSN = "AAA", EmployeeUUID = new Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA") };
            EmployeeToJobTitleMatchLink link21 = new EmployeeToJobTitleMatchLink();
            link21.TheEmployee = e21;
            org20.Links.Add(link21);
            Employee e22 = new Employee() { SSN = "CCC", EmployeeUUID = new Guid("CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC") };
            EmployeeToJobTitleMatchLink link22 = new EmployeeToJobTitleMatchLink();
            link22.TheEmployee = e22;
            org20.Links.Add(link22);

            Organization org30 = new Organization();
            org30.OrganizationSurrogateKey = 30;
            Employee e31 = new Employee() { SSN = "BBB", EmployeeUUID = new Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB") };
            EmployeeToJobTitleMatchLink link31 = new EmployeeToJobTitleMatchLink();
            link31.TheEmployee = e31;
            org30.Links.Add(link31);
            Employee e32 = new Employee();
            e32.SSN = "ZZZ";
            EmployeeToJobTitleMatchLink link32 = new EmployeeToJobTitleMatchLink();
            link32.TheEmployee = e32;
            org30.Links.Add(link32);

            IList<Organization> allOtherOrgsExceptOrg10 = new List<Organization>();
            /* Note, I did not add org10 here */
            allOtherOrgsExceptOrg10.Add(org20);
            allOtherOrgsExceptOrg10.Add(org30);

            IEnumerable<EmployeeToJobTitleMatchLink> matches1 =
            org10.Links.Where(org10Link => org20.Links.Any(org20Link => org20Link.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));

            IEnumerable<EmployeeToJobTitleMatchLink> matches2 = null;
            //org10.Links.Where(org10Link  =>  ( allOtherOrgs.Where ( anyOtherOrg  => anyOtherOrg.Links.Any(dbSideChild => dbSideChild.TheEmployee.SSN == org10Link.TheEmployee.SSN)) );

            if (null != matches1)
            {
                foreach (EmployeeToJobTitleMatchLink link in matches1)
                {
                    Console.WriteLine(string.Format("matches1, SSN = {0}", link.TheEmployee.SSN));
                }
            }
            if (null != matches2)
            {
                foreach (EmployeeToJobTitleMatchLink link in matches2)
                {
                    Console.WriteLine(string.Format("matches2, SSN = {0}", link.TheEmployee.SSN));
                }
            }

Linq:正在将1个子集合与(聚合)子集合进行比较

matches2 =
            allOtherOrgsExceptOrg10.SelectMany(x => x.Links)
                .Where(x => org10.Links.Select(o => o.TheEmployee.SSN).Contains(x.TheEmployee.SSN));

您可以使用allOther集合上的SelectMany来选择所有组织的所有链接。然后检查组织10列表中是否有任何SSN。

请参阅:http://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.100).aspx

您可以使用SelectMany来展开集合,然后像使用火柴1 一样使用它

IEnumerable<EmployeeToJobTitleMatchLink> matches2 =
            org10.Links.Where(
                org10Link =>
                allOtherOrgsExceptOrg10.SelectMany(allOtherOrgs => allOtherOrgs.Links).Any(
                    anyOtherLink =>
                    anyOtherLink.TheEmployee.SSN.Equals(org10Link.TheEmployee.SSN, StringComparison.OrdinalIgnoreCase)));

SelectMany将使其看起来像一个IEnumerable,而不是IEnumeraable的IEnumerable。