3

I have method that updates the properties of a class and then updates that object in the database using a web service. I want to verify that the update succeeded by pulling the new object and comparing it to an object in memory.

Do I need to compare each property or will this determine if they have the same values for all the properties?

var areEqual = objectThatHasChanges.Equals(objectSavedToDatabase);
Jonathan Kittell
  • 7,163
  • 15
  • 50
  • 93
  • You have to compare classes or objects? it sound like you are comparing two objects –  May 29 '15 at 11:16
  • [Object.Equals docs](https://msdn.microsoft.com/en-us/library/bsc2ak47%28v=vs.110%29.aspx), its really your decision as to how much you need to compare to decide what is enough. Are you sure you need to do this at all? It sounds like it might be very expensive – Sayse May 29 '15 at 11:17
  • The objects are entities, I was thinking just go through each property and compare each one but if I can do it with one line and it does the same thing then why not. – Jonathan Kittell May 29 '15 at 11:20
  • Check also this post [here](http://stackoverflow.com/questions/506096/comparing-object-properties-in-c-sharp) it shows the reflection based generic method to compare any two objects which I mentioned in my answer. – Przemysław Ładyński May 29 '15 at 11:32

4 Answers4

3

You will need to compare each property. If these are two reference-type object the equals method will just use default equal implementation which will check the objects are the same instances: https://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx

If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method. Reference equality means that the object variables that are compared refer to the same object. The following example illustrates the result of such a comparison. It defines a Person class, which is a reference type, and calls the Person class constructor to instantiate two new Person objects, person1a and person2, which have the same value. It also assigns person1a to another object variable, person1b. As the output from the example shows, person1a and person1b are equal because they reference the same object. However, person1a and person2 are not equal, although they have the same value.

You should either overload the "Equals" method and write your own which compare each or key properties (like last modify date, revision etc..) or you should write a method which will take these two objects and compare them.

If you have a lot of fields in different objects you can write generic method which uses reflection to iterate through all properties in object and compares with the other. Of course checking first if both objects are of the same type.

2

If the property names are the same, this is more or less trivial:

private static bool IsEqual(Model1 model, Model2 model2)
{
  long changes = 0;

  foreach (var pi in typeof(Model1).GetProperties(BindingFlags.Instance | BindingFlags.Public))
  {
    var secondModelPi = typeof(Model2).GetProperty(pi.Name, BindingFlags.Instance | BindingFlags.Public);
    if (secondModelPi != null)
    {
      if (!pi.GetValue(model).Equals(secondModelPi.GetValue(model2)))
      {
        changes++;
      }
    }
  }

  return changes == 0;
}
zaitsman
  • 8,984
  • 6
  • 47
  • 79
1

If you really want to check if update is successful then do something in this way:

string query = @"UPDATE [Entities] SET [Value] = [Value] + 1";

// SQL initialization

return (sqlCommand.ExecuteNonQuery() > 0);

ExecuteNonQuery returns the number of affected \ inserted rows. Thus, positive result means that update was successful.

If you, for some reasons, want to get entity from server after update then use the following approach:

string query = @"UPDATE [Entities] SET [Value] = [Value] + 1; 
SELECT * FROM [Entities] WHERE [Id] = SCOPE_IDENTITY()"

// SQL initialization

var reader = sqlCommand.ExecuteReader();
while (reader.Read())
{
    // Object initialization
}

These ways are better in terms of convenience and performance.

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
0

To expound upon @zaitsman's answer, if you want to reuse this for multiple different types you would need to use generic types. I also converted the class to an extension method, as in my mind this should work similar to a LINQ query or .Equals.

//'this' Makes this an extension method if you do not want this to be an extension method just remove the 'this' keyword before model
private static bool IsSame<T,T2>(this T model, T2 model2)
    {
        long changes = 0;

        foreach (var pi in typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public))
        {
            var secondModelPi = typeof(T2).GetProperty(pi.Name, BindingFlags.Instance | BindingFlags.Public);
            if (secondModelPi != null)
            {
                if (!pi.GetValue(model).Equals(secondModelPi.GetValue(model2)))
                {
                    changes++;
                }
            }
        }

        return changes == 0;
    }

Example Usage

model.IsSame(model2);
Marcello B.
  • 4,177
  • 11
  • 45
  • 65