C# 比较两个自定义列表对象
我要检查一下 1) 如果来自C# 比较两个自定义列表对象,c#,linq,lambda,C#,Linq,Lambda,我要检查一下 1) 如果来自empDb的任何属性(EmployeeObject)出现在empXml中,则返回true。否则返回false public class EmployeeObject { public Int32 Id { get; set; } public string Title { get; set; } public string Desc { get; set; } ..... } IList<EmployeeObject> e
empDb
的任何属性(EmployeeObject)出现在empXml
中,则返回true
。否则返回false
public class EmployeeObject
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
.....
}
IList<EmployeeObject> empDb = PopulateFromDb(); //calling ado.net
IList<EmployeeObject> empXml = PopulateFromXml(); //deserializing xml
或
如果您没有在
EmployeeObject
类中实现Equals
和GetHashCode
,则将通过引用对员工进行比较。这里肯定会有不同的实例,因为第一个列表是在从数据库读取数据时创建的,第二个列表是在反序列化xml时创建的。因此,即使所有领域价值观相同的员工也会被视为不同的员工
如果只希望按员工Id检查匹配项,则可以将序列投影到Id,然后使用检查匹配项是否存在
// at least one employee with equal Id
empDb.Select(e => e.Id).Intersect(empXml.Select(e => e.Id)).Any()
如果您想通过员工字段的值而不是他们的引用来比较员工,您有几个选项。如果您不能或不想更改EmployeeObject类的实现并重写其Equals和GetHashCode方法,则可以为员工创建自定义的比较器:
public class EmployeeComparer : IEqualityComparer<EmployeeObject>
{
public bool Equals(EmployeeObject x, EmployeeObject y)
{
return x.Id == y.Id
&& x.Title == y.Title
&& x.Desc == y.Desc;
}
public int GetHashCode(EmployeeObject obj)
{
int code = 19;
code = code * 23 + obj.Id.GetHashCode();
code = code * 23 + obj.Title.GetHashCode();
code = code * 23 + obj.Desc.GetHashCode();
return code;
}
}
或者,您可以将员工投影到匿名对象(默认实现为Equals和GetHashCode):
或覆盖这些方法:
public class EmployeeObject
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
public override int GetHashCode()
{
int code = 19;
code = code * 23 + Id.GetHashCode();
code = code * 23 + Title.GetHashCode();
code = code * 23 + Desc.GetHashCode();
return code;
}
public override bool Equals(object obj)
{
EmployeeObject other = obj as EmployeeObject;
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
return Id == other.Id &&
Title == other.Title && Desc == other.Desc;
}
}
你的代码也能用。或者您可以使用Intersect:
empDb.Intersect(empXml).Any()
如果您没有在
EmployeeObject
类中实现Equals
和GetHashCode
,则将通过引用对员工进行比较。这里肯定会有不同的实例,因为第一个列表是在从数据库读取数据时创建的,第二个列表是在反序列化xml时创建的。因此,即使所有领域价值观相同的员工也会被视为不同的员工
如果只希望按员工Id检查匹配项,则可以将序列投影到Id,然后使用检查匹配项是否存在
// at least one employee with equal Id
empDb.Select(e => e.Id).Intersect(empXml.Select(e => e.Id)).Any()
如果您想通过员工字段的值而不是他们的引用来比较员工,您有几个选项。如果您不能或不想更改EmployeeObject类的实现并重写其Equals和GetHashCode方法,则可以为员工创建自定义的比较器:
public class EmployeeComparer : IEqualityComparer<EmployeeObject>
{
public bool Equals(EmployeeObject x, EmployeeObject y)
{
return x.Id == y.Id
&& x.Title == y.Title
&& x.Desc == y.Desc;
}
public int GetHashCode(EmployeeObject obj)
{
int code = 19;
code = code * 23 + obj.Id.GetHashCode();
code = code * 23 + obj.Title.GetHashCode();
code = code * 23 + obj.Desc.GetHashCode();
return code;
}
}
或者,您可以将员工投影到匿名对象(默认实现为Equals和GetHashCode):
或覆盖这些方法:
public class EmployeeObject
{
public Int32 Id { get; set; }
public string Title { get; set; }
public string Desc { get; set; }
public override int GetHashCode()
{
int code = 19;
code = code * 23 + Id.GetHashCode();
code = code * 23 + Title.GetHashCode();
code = code * 23 + Desc.GetHashCode();
return code;
}
public override bool Equals(object obj)
{
EmployeeObject other = obj as EmployeeObject;
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
return Id == other.Id &&
Title == other.Title && Desc == other.Desc;
}
}
你的代码也能用。或者您可以使用Intersect:
empDb.Intersect(empXml).Any()
如果
Id
是您可能要写入的实体的主键:
var set = new HashSet<int>(empXml.Select(x => x.Id)); //For faster lookup
empDb.Any(a => set.Contains(a.Id));
然后写下:
var set = new HashSet<EmployeeObject>(empXml); //For faster lookup
empDb.Any(a => set.Contains(a));
var set=newhashset(empXml)//以加快查找速度
empDb.Any(a=>set.Contains(a));
如果Id
是您可能要编写的实体的主键:
var set = new HashSet<int>(empXml.Select(x => x.Id)); //For faster lookup
empDb.Any(a => set.Contains(a.Id));
然后写下:
var set = new HashSet<EmployeeObject>(empXml); //For faster lookup
empDb.Any(a => set.Contains(a));
var set=newhashset(empXml)//以加快查找速度
empDb.Any(a=>set.Contains(a));
您是否在EmployeeObject
类中实现了Equals
和GetHashCode
?如果没有,那么如果您将有两个id相同但标题不同的对象呢?您是否在EmployeeObject
类中实现了Equals
和GetHashCode
?如果没有,那么如果您将有两个具有相同id但标题不同的对象呢;如果我必须与Title或Desc或Id
进行比较,有没有办法创建一个方法而不是创建三个?还有,在我的问题中,我的代码有什么问题?为什么不起作用?@AbuHamzah我已经在第一段解释了为什么你的代码不起作用。如果要比较多个属性,请重写类的Equals
和GetHashCode
,或者创建自定义比较器并将其传递给Intersect
好的,我得到了它;我必须与Title、Desc或Id进行比较,有没有办法创建一个方法而不是创建三个?我能做的一个方法是添加if-else语句
,但还有其他更好的处理方法吗。代码19和23是什么?是你选择的随机数吗?@AbuHamzah,这是素数-生成非常独特的散列的方法之一,看看如果;如果我必须与Title或Desc或Id
进行比较,有没有办法创建一个方法而不是创建三个?还有,在我的问题中,我的代码有什么问题?为什么不起作用?@AbuHamzah我已经在第一段解释了为什么你的代码不起作用。如果要比较多个属性,请重写类的Equals
和GetHashCode
,或者创建自定义比较器并将其传递给Intersect
好的,我得到了它;我必须与Title、Desc或Id进行比较,有没有办法创建一个方法而不是创建三个?我能做的一个方法是添加if-else语句
,但还有其他更好的处理方法吗。代码19和23是什么?是你选择的随机数吗?@AbuHamzah,这是素数-生成非常独特的散列的方法之一,请参阅我对Sergeyse的回复我对Sergey的回复