0

First we pull in new alerts and deserialize them. Now I only care about 2 properties that need to be compared: CommandID and AlertID, all others can be ignored so I create a new object which I assumed would have been easier to compare the results. All other properties become null.

List<AlertModel> alerts = JsonConvert.DeserializeObject<List<AlertModel>>(json)
.Select(x => new AlertModel() { CommandID = x.CommandID, AlertID = x.AlertID }).ToList();

Now I want to find new alerts that don't already exist

List<AlertModel> newAlerts = alerts.Except(currentAlerts).ToList();

Next we pull what alerts already exist.

List<AlertModel> existingAlerts = currentAlerts.Intersect(alerts).ToList();

Now we store new and existing alerts.

currentAlerts.Clear();
currentAlerts.AddRange(newAlerts);
currentAlerts.AddRange(existingAlerts);

1st run alerts contains 1 item newAlerts contains 1 item and existingAlerts contains 0 as they should.

2nd run through isn't what I was expecting.

alerts contains 1 as it should.

newAlerts contains 1 and this should be 0. currentAlerts contains the exact same CommandID and AlertID as in alerts

existingAlerts contains 0 and this should be 1 since the same CommandID and AlertID exists in currentAlerts and alerts.

Not sure what i'm missing here and maybe there is a better way to do this.

Tsukasa
  • 6,342
  • 16
  • 64
  • 96
  • 4
    Did you implement correctly `GetHashCode` and `Equals` in your `AlertModel` class? – Ivan Stoev Oct 12 '16 at 12:47
  • I have not can you provide an example or point me to a post about it. – Tsukasa Oct 12 '16 at 12:54
  • [MSDN](https://msdn.microsoft.com/en-us/library/ms182358.aspx) is a place to start. [This](https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx) too. Or [this](http://stackoverflow.com/q/10454519/6400526) – Gilad Green Oct 12 '16 at 12:57

3 Answers3

1

Override Equals and GetHashCode in your AlertModel class. Return a constant value in GetHashCode() (e.g. -1) if you want to force to call your Equals method.

public override bool Equals(object obj)
{
    var that = obj as AlertModel;

    return that != null && that.AlertId == this.AlertId && that.CommandId == this.CommandId; 
}

public override int GetHashCode()
    {           
        int hash = 13;
        return (this.AlertId.GetHashCode() * this.CommandID.GetHashCode()) ^ hash;
    }
Andras Sebo
  • 1,120
  • 8
  • 19
1

Replace this code:

List<AlertModel> newAlerts = alerts.Except(currentAlerts).ToList();

Whit this:

List<AlertModel> newAlerts = alerts.Where(x => !currentAlerts.Any(y => y.CommandID == x.CommandID && y.AlertID == x.AlertID)).ToList();

The issue is that your alerts list contains new elements (new AlertModel() { CommandID = x.CommandID, AlertID = x.AlertID }). This is a reference problem.

Animal a = new Animal { Color = "Red" };
Animal b = new Animal { Color = "Red" };
a == b; // This returns false

Alternatively you can override Equals method in you class. To do this in your class:

public class AlertModel {
    // Some things

    public override bool Equals(object model) {
        return model != null && CommandID == model.CommandId && AlertID == model.AlertID;
    }
}
erikscandola
  • 2,854
  • 2
  • 17
  • 24
0
var uniqueAlerts = alerts.Where(a=> !currentAlerts.Any(c=> c.CommandID == a.CommandID && c.AlertID== a.AlertID));
S.N
  • 4,910
  • 5
  • 31
  • 51