简体   繁体   English

C#将两个集合连接在一起

[英]C# Joining two collections together

Pretty new in C# trying to Join two collections together, where the final result will provide all data from both collections. C#中的新功能,试图将两个集合连接在一起,最终结果将提供两个集合的所有数据。 Right now the code returns only matched documents. 现在,该代码仅返回匹配的文档。 Thank you. 谢谢。

//Collections
   IQueryable collection1 = database.GetCollection("MainData").AsQueryable();
   IQueryable collection2 = database.GetCollection("SecondaryData").AsQueryable(); 

          var result = collection2.Join(collection1, a => a.ID, b => b.ID, (a, b) => new { a, b })
                .ToList()
                .Select(s => new ViewModel.Customer()
                {
                    ID = s.b.ID,
                    FirstName = s.b.FirstName
                    LastName = s.b.LastName
                }).ToList();


            return result;

Ok, so you have two queries to fetch sequences of different types, let's say ClassA and ClassB . 好的,所以您有两个查询来获取不同类型的序列,比如说ClassAClassB Both types have a property Id , and you want some kind of join on this Id. 两种类型都有一个属性Id ,并且您想要对该ID进行某种连接。

... where the final result will provide all data from both collections ...最终结果将提供两个集合的所有数据

It's good to realize there are various types of Joins. 很高兴意识到存在各种类型的联接。 The join you coded is the most simple join, quite often called an inner join . 您编码的联接是最简单的联接,通常称为inner join Only elements that have matching Ids are in the resulting sequence. 结果序列中只有具有匹配ID的元素。 So if you've got a ClassA with Id = 3, but there is no ClassB with this Id, then it won't be in your result. 因此,如果您拥有Id = 3的ClassA,但没有具有此Id的ClassB,那么它将不会出现在您的结果中。

IQueryable<ClassA> itemsA = ...
IQueryable<ClassB> itemsB = ...

var innerJoinResult = itemsA.Join(itemsB,   // inner join A and B
    itemA => itemA.Id,                      // from each itemA take the Id
    itemB => itemB.Id,                      // from each itemB take the Id
    (itemA, itemB) => new                   // when they match make a new object
    {                                       // where you only select the properties you want
        NameA = itemA.Name,
        NameB = itemB.Name,
        BirthdayA = itemA.Birthday,
        ...
    });

If you also want the items without matching Id, so all itemsA without a matching itemB.Id and all itemsB without a matching itemA.Id, you'll have to do a full outer join. 如果您还希望项目没有匹配的ID,那么所有没有匹配的itemB.Id的itemsA和没有匹配的itemA.Id的所有itemB,则必须进行完全外部联接。 This seems to be what you meant when you wrote: 这似乎是您写时的意思:

... where the final result will provide all data from both collections ...最终结果将提供两个集合的所有数据

LINQ does not have this functionality as a standard, but you can write an extension method for it. LINQ没有此功能作为标准,但是您可以为其编写扩展方法。

See this excellent 2nd answer in stackoverflow for a LINQ extension function for a full outer join . 有关完整外部联接的LINQ扩展功能,请参见stackoverflow中的出色的第二个答案

Also see Extension Methods Demystified 另请参阅扩展方法揭秘

You could use Concat which will return the items from the first collection followed by the items from the second collection: 您可以使用Concat ,它将返回第一个集合的项目,然后返回第二个集合的项目:

var combined = collection1.Concat(collection2);

Or you could use Union which will return distinct values from both collections: 或者,您可以使用Union ,它将从两个集合中返回不同的值:

var combined = collection1.Union(collection2);

You can do this by also doing a reverse join from collection1 onto collection2 and then UNION on the results. 为此,您还可以从collection1到collection2进行反向联接,然后对结果进行UNION

    var resultSet1 = collection2.Join(collection1, a => a.ID, b => b.ID, (a, b) => new { a, b })
          .ToList()
          .Select(s => new ViewModel.Customer()
          {
              ID = s.b.ID,
              FirstName = s.b.FirstName,
              LastName = s.b.LastName
          }).ToList();

    var resultSet2 = collection1.Join(collection2, a => a.ID, b => b.ID, (a, b) => new { a, b })
            .ToList()
            .Select(s => new ViewModel.Customer()
            {
                ID = s.b.ID,
                FirstName = s.b.FirstName,
                LastName = s.b.LastName
            }).ToList();


    return resultSet1.Union(resultSet2);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM