【问题标题】:comparing two objects for values without listing every column比较两个对象的值而不列出每一列
【发布时间】:2017-08-29 15:20:15
【问题描述】:

Web 服务导入数据并存储在业务逻辑Graph.AddressList 中。如果找到匹配项,请添加到 keepList。 问题是数据完全相同,但没有被添加到保留列表中。例如,数据库中记录中的 ENTITYKEY 已填充,但未在 Xml 中填充,而无需写出数据库中的每一列以匹配 xmlRecord 中的每一列。有没有办法解决这个问题?

// Fetch List Of Addresses
List<Address> updateAddressList = DbContext.GraphAddressList.Where<Address>(p => p.PersonnelNo == action.PersonnelNo).ToList<Address>();

////IF ADDRESS EXISTS IN THE DB, BUT NOT IN THE XML FILE, REMOVE FROM DB
List<Address> keepList = new List<Address>();
foreach (Address recordInDB in updateAddressList)
{
    foreach (Address_0006 recordInXML in Graph.AddressList)
    {
        if (recordInDB == recordInXML)
        {                                                        
            keepList.Add(recordInDB);
        }
    }
}

List<Address> removeList = updateAddressList.Except(keepList).ToList();
foreach (Address record in removeList)
{                                           
    DbContext.AddressList.DeleteObject(record);
}

感谢您的回复,所以我真的需要创建一个类

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

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

    return this.RecommendationId.Equals(item.RecommendationId);
}

public override int GetHashCode()
{
    return this.RecommendationId.GetHashCode();
}

【问题讨论】:

    标签: c# entity-framework equals


    【解决方案1】:

    recordInDBrecordInXML 是自定义对象,要检查它们是否相等,您必须:

    1. 为它们覆盖EqualsGetHashCodeCorrect way to override Equals() and GetHashCode()
    2. 实现IEqualityComparer:How to use the IEqualityComparer
    3. 让你的一个类实现IEquatable&lt;T&gt;,其中T是另一个类的类型

    这样做,对象将根据它们所具有的属性进行比较。目前(x == y)检查的是引用是否相等——两个不同的实例意味着false。这样做之后,比较时你也应该使用recordInDB.Equals(recordInXML)

    实现后你还可以重构一下:

    var keepList = recordInDB.Where(record => Graph.AddressList.Contains(record));
    var removeList = updateAddressList.Except(keepList).ToList();
    foreach (Address record in removeList)
    {                                           
        DbContext.AddressList.DeleteObject(record);
    }
    

    使用选项 3,然后在您的 Address_0006 中实现 IEquatable&lt;Address&gt;

    public class Address_0006 : IEquatable<Address>
    {
        public bool Equals(Address other)
        {
            // Compare here that each of the relevant properties in this (Address_0006) 
            // equals the corresponding property in other (Address)
        }
    }
    

    【讨论】:

    • 添加一些有趣的 linq var removeList = updateAddressList.Except(keepList).ToList().ForEach(x =&gt; DbContext.AddressList.DeleteObject(x)); :p
    • @Uknown - true :) 可能。我个人不会过多地使用.ForEach。一个人也可以拥有所有的功能是一个线:updateAddressList.Except(recordInDB.Where(record =&gt; Graph.AddressList.Contains(record))).ToList().ForEach(x =&gt; DbContext.AddressList.DeleteObject(x));但这有点太多了哈哈
    • @John - 我认为不要写一个通用的 EqualityComparer 而只是为你的类型写一个特定的
    • @Gilad Green 更简单!哈。我对 linq 的唯一问题是调试起来会很痛苦,而且如果它变得太复杂,也不一定能读到最好的
    • 对不起,我还在学习……所以请再看一遍原Q..ta
    【解决方案2】:

    您可以反映AddressAddress_0006 类型的属性,并检查同名属性是否包含相同的数据。但是反射比较慢,所以除非你有数百个属性并且它们经常更改,否则我建议手动编写比较。

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多