C#中的新功能尝试将两个集合连接在一起,最终结果将提供来自两个集合的所有数据。现在代码只返回匹配的文档。谢谢。
//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;
答案 0 :(得分:2)
好的,所以你有两个查询来获取不同类型的序列,让我们说ClassA
和ClassB
。这两种类型都有一个属性Id
,您希望在此Id上进行某种连接。
...最终结果将提供来自两个集合的所有数据
很高兴认识到有各种类型的联接。您编码的连接是最简单的连接,通常称为inner join
。只有具有匹配ID的元素才会出现在结果序列中。因此,如果你有一个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,
...
});
如果你还想要没有匹配Id的项目,那么没有匹配的itemB.Id的所有itemsA和没有匹配的itemA.Id的所有itemsB,你必须做一个完整的外部联接。这似乎就是你写的时候的意思:
...最终结果将提供来自两个集合的所有数据
LINQ没有此功能作为标准,但您可以为其编写扩展方法。
See this excellent 2nd answer in stackoverflow for a LINQ extension function for a full outer join
答案 1 :(得分:1)
您可以使用
Concat
来返回第一个项目 集合后跟第二个集合中的项目:
var combined = collection1.Concat(collection2);
或者你可以使用
Union
来返回两者的不同值 集合:
var combined = collection1.Union(collection2);
答案 2 :(得分:1)
你可以通过从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);