John
John

Reputation: 3945

comparing two objects for values without listing every column

Web serivce imports data and stores in business logic Graph.AddressList. If match found, add to keepList. Problem is the data is exactly the same but it is not being added to the keep list. For example ENTITYKEY in record in database is populated but not in the Xml without writing out every column in the database to match every column in the xmlRecord. Is there a way around this?

// 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);
}

Thanks for reply so really I need to do create a class

 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();
}

Upvotes: 1

Views: 66

Answers (2)

Gilad Green
Gilad Green

Reputation: 37281

recordInDB and recordInXML are custom objects and to check if they are equal you must:

  1. Override Equals and GetHashCode for them: Correct way to override Equals() and GetHashCode()
  2. Implement an IEqualityComparer: How to use the IEqualityComparer
  3. Make one of your classes implement IEquatable<T> where T is the type of the other class

Doing so the objects will be compared by the properties they have. Currently (x == y) what is checked is if the reference is equal - which by being two different instances means false. After doing so, when comparing you should also use recordInDB.Equals(recordInXML)

After implementing such you can also refactor a bit:

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

Going with option 3 then in your Address_0006 implement the IEquatable<Address>:

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)
    }
}

Upvotes: 4

Haukinger
Haukinger

Reputation: 10883

You could reflect over the properties of the Address and Address_0006 types and check that equally named properties contain equal data. But reflection is rather slow, so unless you have hundreds of properties and they frequently change, I suggest manually writing the comparison.

Upvotes: 0

Related Questions