Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较两个自定义列表对象_C#_Linq_Lambda - Fatal编程技术网

C# 比较两个自定义列表对象

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

我要检查一下

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> 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的回复