C# Linq 完全外连接重复值

标签 c# linq outer-join

我有两个具有这种类型的 IQueryable 集合

public class Property  
{  
   public string Name {get; set;}  
}

集合 1,具有以下名称值:

A  
A  
A  
B  

集合 2,具有以下名称值:

A  
B  
B

我想要得到的是第三个集合,其中集合 1 和集合 2 的名称值匹配,如果没有匹配,则为 null(空),如下所示:

Result Collection:  

A     A
A     null  
A     null  
B     B  
null  B

如何使用 C#、LINQ 实现这一目标?

最佳答案

using System;
using System.Collections.Generic;
using System.Linq;    

namespace Testing
{
    public class Property
    {
        public string Name { get; set; }

        public override bool Equals(object obj)
        {
            var item = obj as Property;

            if (item == null)
            {
                return false;
            }
            return item.Name == Name;
        }

        public override int GetHashCode()
        {
            return Name.GetHashCode();
        }
    }

    public class JoinedProperty
    {
        public Property Name1 { get; set; }
        public Property Name2 { get; set; }

        public override string ToString()
        {
            return (Name1 == null ? "" : Name1.Name)
                + (Name2 == null ? "" : Name2.Name);
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var list1 = new List<Property>
            {
                new Property{ Name = "A" },
                new Property{ Name = "A" },
                new Property{ Name = "A" },
                new Property{ Name = "B" }
            };

            var list2 = new List<Property>
            {
                new Property{ Name = "A" },
                new Property{ Name = "B" },
                new Property{ Name = "B" }
            };

            var allLetters = list1.Union(list2).Distinct().ToList();

            var result = new List<JoinedProperty>();

            foreach (var letter in allLetters)
            {
                var list1Count = list1.Count(l => l.Name == letter.Name);
                var list2Count = list2.Count(l => l.Name == letter.Name);

                var matchCount = Math.Min(list1Count, list2Count);

                addValuesToResult(result, letter, letter, matchCount);

                var difference = list1Count - list2Count;

                if(difference > 0)
                {
                    addValuesToResult(result, letter, null, difference);                   
                }
                else
                {
                    difference = difference * -1;
                    addValuesToResult(result,null, letter, difference);                   
                }
            }
            foreach(var res in result)
            {
                Console.WriteLine(res.ToString());
            }
            Console.ReadLine();                
        }

        private static void addValuesToResult(List<JoinedProperty> result, Property letter1, Property letter2, int count)
        {
            for (int i = 0; i < count; i++)
            {
                result.Add(new JoinedProperty
                {
                    Name1 = letter1,
                    Name2 = letter2
                });
            }
        }
    }
}

运行这个,你会得到结果

AA
A
A
BB
B

结果列表的内容就是你要的。

编辑:更新我的答案以使用指定的属性。

关于C# Linq 完全外连接重复值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47844124/

相关文章:

c# - 使用 C# 从 LINQ Query DateTime 字段计算年龄(或年份)进行比较(Age From)

SQL:从连接中收集右手值

mysql : how to retrieve a list of row where one field doesn't contain a specific value from an ENUM

c# - 当使用 'this'关键字时系统如何知道使用什么?

c# - LinqTo 实体中的日期部分相等

c# - 从通用 List<t> 中删除项目

sql - 在关联表上左连接

c# - 使用 Web 服务将文件上传到 Sharepoint 2013 - 对象引用未设置为对象的实例

javascript - SQLDependency OnChange 事件产生无限循环

.net - 有没有一种好方法可以检测 Linq-To-Entities 查询中的空结果?