1

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();
}
John
  • 3,965
  • 21
  • 77
  • 163

2 Answers2

4

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)
    }
}
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
  • add some linq for fun `var removeList = updateAddressList.Except(keepList).ToList().ForEach(x => DbContext.AddressList.DeleteObject(x));` :p – ArcX Aug 29 '17 at 06:58
  • @Uknown - true :) possible. I personally don't use `.ForEach` too much. One can also have all the function is a one-liner: `updateAddressList.Except(recordInDB.Where(record => Graph.AddressList.Contains(record))).ToList().ForEach(x => DbContext.AddressList.DeleteObject(x));` but that is a bit too much haha – Gilad Green Aug 29 '17 at 07:00
  • @John - I think do not write a generic EqualityComparer but just a specific one for your types – Gilad Green Aug 29 '17 at 07:01
  • @Gilad Green Even simpler! ha. The only problem I have with linq is it can be a pain to debug and doesn't always read the best if it gets too complex – ArcX Aug 29 '17 at 07:01
  • Sorry man Im still learning...so please see original Q again..ta – John Aug 29 '17 at 07:07
  • @John - that's fine :) Basically what you need is a way to tell how to compare these two objects. The default for reference type is if the reference is the same. You want to do one of the 3 options I noted above in order to do so. As you are comparing two different classes then go with option 3 IMO – Gilad Green Aug 29 '17 at 07:08
  • ahh ok I get you now but is that just not the same as originally having if (recordInDB.a == recordInXML.a && recordInDB.b == recordInXML.b && recordInDB.c == recordInXML.c) etc... – John Aug 29 '17 at 07:14
  • @John - it does :) But encapsulating this logic in a proper function to it is better OOP ;) also... if you need that logic in another place.. Last, note that here too if one of the properties is not a value type or string then you need to use `.Equals` – Gilad Green Aug 29 '17 at 07:15
  • What about any of the first 2 suggestions you give me? I just wanted to compare tow objects without having to write everything out...I have alot to compare and little time to do it I was hoping for something shorter...again thanks for the reply – John Aug 29 '17 at 07:16
  • @John - the two first ones aren't really that different. The first is to being able to compare two objects of the same type. You can see in other SO questions about when to use which – Gilad Green Aug 29 '17 at 07:18
  • @GiladGreen yes I looked at te link you posted which i always just added to the bottom of the originalQ, but how does it compare the two objects when only one is passed in? – John Aug 29 '17 at 07:20
  • or is it as simple to say public bool Equals(Address_0006 x, Address_0006 y) { return x.Numf == y.Numf; } – John Aug 29 '17 at 07:22
  • @John - because the one is the current, the `this` and the other is the one that is passed. For example: `x.Equals(y)` - x is the `this` (and you need to implement the method in the class of `x`) and `y` is the other – Gilad Green Aug 29 '17 at 07:23
  • @John - is all you need to compare between the tow is the `Numf` property? – Gilad Green Aug 29 '17 at 07:24
  • the numf propery doesnt exist? this is EF im using if that is why – John Aug 29 '17 at 07:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/153090/discussion-between-gilad-green-and-john). – Gilad Green Aug 29 '17 at 07:28
  • @John - did you understand the third example? – Gilad Green Aug 31 '17 at 05:46
  • @John - glad it helped :) – Gilad Green Aug 31 '17 at 05:52
0

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.

Haukinger
  • 10,420
  • 2
  • 15
  • 28