C# 如何使用LINQ查找重复对象

C# 如何使用LINQ查找重复对象,c#,linq,C#,Linq,我有一个Employee类,它具有以下内容: public class Employee { //EmployeeNumber cannot be the same as the Id public int EmployeeNumber {get; set; } public string EmployeeName {get; set } } 最终,我将用新员工更新数据库。我有一个新员工的列表,还有数据库中现有员工的列表。员工姓名可以相同,但EmployeeNumber必须唯一。我

我有一个Employee类,它具有以下内容:

public class Employee
{
  //EmployeeNumber cannot be the same as the Id
  public int EmployeeNumber {get; set; }
  public string EmployeeName {get; set }
}
最终,我将用新员工更新数据库。我有一个新员工的列表,还有数据库中现有员工的列表。员工姓名可以相同,但EmployeeNumber必须唯一。我希望最终有一个重复的员工列表,它是通过比较我将要添加到数据库中的列表与表示数据库中的内容的员工列表而创建的


使用LINQ获取重复员工列表的最佳方法是什么?

您只需检查新员工列表中当前员工的EmployeeNumber是否可用

 List<Employee> currentEmployees = ...
 List<Employee> newEmployees = ...

 List<Employee> duplicateEmployees = currentEmployees.Where(currentEmployee => (newEmployees.Select(f => f.EmployeeNumber)).Contains(currentEmployee.EmployeeNumber)).ToList();
列出当前员工=。。。
列出新员工=。。。
列出重复的Employees=currentEmployees.Where(currentEmployees=>(newEmployees.Select(f=>f.EmployeeNumber)).Contains(currentEmployees.EmployeeNumber)).ToList();

正确的方法是将
EmployeeNumber
声明为表键,这样就不需要检查重复项

public class Employee
{
  [Key]
  public int EmployeeNumber {get; set; }
  public string EmployeeName {get; set }
}
在数据库中,您还可以将
EmployeeNumber
声明为主键。 假设您使用的是SQL Server,您可以添加
Identity(1,1)
使其自动递增

下面是表定义的示例:

CREATE TABLE Persons
(
  EmployeeNumber int IDENTITY(1,1) PRIMARY KEY,
  EmployeeName varchar(255) NOT NULL,
)

我不确定它是否是最有效的(该奖项归@Fahad的评论)

假设您的意思是“如何获取出现在两个集合中的记录列表”,我喜欢使用
Join
GroupJoin
方法,因为您可以选择一个新集合,或者选择包含两个集合中记录的匿名类型

语法是
Join(此集合1、集合2、FuncCollection1Key、Funccollection2Key、FuncOutputSelection)。

因此,如果您的“新”集合是IEnumerable NewEmployees,而您的现有集合是
IEnumerable DbEmployees
,则您的重复雇员集合由以下公式导出:

var DupeEmployees=NewEmployees.Join(DbEmployees,n=>n.EmployeeNumber,d=>d.EmployeeNumber,(nEmp,dbEmp)=>nEmp)

两个“中间”lambda表达式必须是产生相同类型值(实现IEquatable)的函数,但没有其他限制。您有两个不同类型的集合,可以输出任何您喜欢的内容


现在,最好的方法是Farhad的建议,在这种情况下使用
Join
有点像用大象枪射杀蜜蜂,但是理解
Join
会给你带来很多好处。

你可以实现IEqualityComparer并使用LinQ方法“Except”

公共类MyComparer:IEqualityComparer
{
公共布尔等于(员工x,员工y)
{
返回x.EmployeeNumber等于(y.EmployeeNumber);
}
public int GetHashCode(员工x)
{
返回x.EmployeeNumber.GetHashCode()
}
}

可能重复将EmployeeNumber声明为表键,则无需检查duplicates@bkribbs我想他是在问,如何确认“新”员工列表在现有数据库中没有已保存的记录。@FahadJameel,你是对的,但请将该评论作为“答案”提交没有评论。如果您提供代码来实现您的建议,则可获得奖励。@MichaelBlackburn我没有在此处显示,但员工也有一个唯一的密钥,但在应用程序中,密钥不能与员工编号相同。键是常量,但员工编号可能会被用户更改-我会将其添加到代码段这是我想做的,我基本上需要出现在用户试图上传内容中的员工姓名列表,以及数据库中已有的内容。如果列表为空,则我可以继续,否则向用户报告哪些员工已经存在。抱歉,如果我没有说清楚,如果您只需要EmployeeName,请选择lambda
(nEmp,dbEmp)=>nEmp.EmployeeName
如果您需要查看这两个对象(例如,它们可能需要合并),您可以创建一个新的匿名类型:
(nEmp,dbEmp)=>new{IncomingEmployee=nEmp,ExistingEmployee=dbEmp}
当在同一类型的对象之间进行比较,并且比较复杂或经常执行时,这是一种非常好的技术。
public class MyComparer : IEqualityComparer<Employee>
{
    public bool Equals(Employee x, Employee y)
    {
        return x.EmployeeNumber.Equals(y.EmployeeNumber);
    }

    public int GetHashCode(Employee x)
    {
        return x.EmployeeNumber.GetHashCode()
    }
}