2014-01-21 2 views
3

В какой-то момент во время моего приложения у меня есть словарь данных из запроса базы данных. Я беру эти данные и экземпляр объекта и вызываю метод RestoreState(), который принимает словарь данных и применяет значения к соответствующим свойствам в новом экземпляре.Определение значений неравновесных значений с использованием Lambda в C#

Когда метод RestoreState() завершен, я затем передать словарь значений объекта в свойство под названием OriginalValues, как например:

myObject.EnableChangeTracking = true; 
myObject.OrginalValues = dictionaryData; 

Позже, пользователь делает некоторые изменения объекта с помощью пользовательского интерфейса и нажимает save. Затем я хочу сравнить существующее состояние свойств объектов с исходным состоянием, поэтому я могу построить оператор обновления для отправки на SQL.

Проблема (и вопрос) заключается в том, что мое выражение lambda для сравнения моего текущего значения свойства со значением в словаре не работает. Словарь OriginalValues содержит 23 элемента, а возвращаемый словарь из моей Lambda содержит 14. В моем модульном тесте я меняю только 2. Почему я возвращаю 12 дополнительных значений, которые не изменились? Метод

Мои GetChanges:

public Dictionary<string, object> GetChanges() 
    { 
     if(!EnableChangeTracking || OrginalValues==null || !OrginalValues.Any()) 
      return new Dictionary<string, object>(); 

     // Only get properties that have changed. 
     var changedProperties = 
      this 
      .GetType() 
      .GetProperties() 
      .Where(p => p.GetValue(this, null) != OrginalValues[p.Name]) 
      .ToDictionary(p => p.Name, p => p.GetValue(this)); 

     return changedProperties; 
    } 

Мой OriginalValues словарь содержит:

  • [0] {[AssetID, 1]} System.Collections.Generic.KeyValuePair
  • [1] { [SubFeatureId, 0]} System.Collections.Generic.KeyValuePair
  • [2] {[OrgNumber, 8555]} System.Collections.Generic.KeyValuePair
  • [3] {[LaneLocationId,]} System.Collections.Generic.KeyValuePair
  • [4] {[StatusId, 1]} System.Collections.Generic.KeyValuePair
  • [5] {[AssetCode, 1] } System.Collections.Generic.KeyValuePair
  • [6] {[Примечание, Там нет ничего, чтобы видеть здесь.]} System.Collections.Generic.KeyValuePair
  • [7] {[DateActivated, 1/21/2014 9 : 12: 08 AM]} System.Collections.Generic.KeyValuePair
  • [8] {[DateInactivated, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [9] {[Введен, JS]} System.Collections.Generic.KeyValuePair
  • [10] {[DateEntered, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [11] {[CreatedBy, JS]} System.Collections.Generic.KeyValuePair
  • [12] {[UpdatedBy, JS]} System.Collections.Generic.KeyValuePair
  • [13] {[DateCreated, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [14] {[DateUpdated, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [15] {[IsActive, True]} System.Collections.Generic.KeyValuePair
  • [16] {[AssetAttributes, System.Collections.Generic.List`1 [FISDC.Models.AssetAttribute]]} System.Collections.Generic.KeyValuePair
  • [17] {[AssetReasons, System.Collections.Generic .List`1 [FISDC.Models.AssetReason]]} System.Collections.Generic.KeyValuePair
  • [18] {[AssetObjects, System.Collections.Generic.List`1 [FISDC.Models.AssetObject]]} System.Collections.Generic.KeyValuePair
  • [19] {[SubFeature,]} System.Collections.Generic.KeyValuePair
  • [20] {[EnableChangeTracking, Ложные]} System.Collections.Generic.KeyValuePair
  • [21] {[IsValid, Ложные]} System.Collections.Generic.KeyValuePair
  • [22] {[OrginalValues,]} System.Collections.Generic.KeyValuePair

и мои лямбда-выражение возвращает:

  • [0] {[AssetID, 1]} System.Collections.Generic.KeyValuePair
  • [1] {[SubFeatureId, 0]} System.Collections.Generic. KeyValuePair
  • [2] {[OrgNumber, 2222]} System.Collections.Generic.KeyValuePair
  • [3] {[StatusId, 1]} System.Collections.Generic.KeyValuePair
  • [4] {[DateActivated , 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [5] {[DateInactivated, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [6] {[DateEntered, 1/21/2014 9:12:08 AM] } System.Collections.Generic.KeyValuePair
  • [7] {[CreatedBy, SomeoneElse]} System.Collections.Generic.KeyValuePair
  • [8] {[DateCreated, 1/21/2014 9:12:08 AM] } System.Collections.Generic.KeyValuePair
  • [9] {[DateUpdated, 1/21/2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
  • [10] {[IsActive, True] } System.Collections.Generic.KeyValuePair
  • [11] {[Ena bleChangeTracking, True]} System.Collections.Generic.KeyValuePair
  • [12] {[IsValid, Ложные]} System.Collections.Generic.KeyValuePair
  • [13] {[OrginalValues, System.Collections.Generic.Dictionary` 2 [System.String, System.Object]]} System.Collections.Generic.KeyValuePair

единственные свойствами я изменил в моем модульном тесте были OrgNumber и CreatedBy. У кого-нибудь есть идеи?

Update

Ниже код я использую, чтобы обновить свойства, а затем вызвать метод GetChanges().

 myObject.OrgNumber = "2222"; 
     myObject.CreatedBy = "SomeoneElse"; 

     myDictionary = myObject.GetChanges(); 

Update 2

Мне интересно, если проблема в том, что мой словарь <string, object> и я сравниваю против обоих ссылочных и не ссылочные типы? Итак, значение int сравнивается с объектом и возвращается? Я не знаю.

Update 3

метод работы благодаря @TTat

public Dictionary<string,object> OrginalValues { get; set; } 

    public Dictionary<string, object> GetChanges() 
    { 
     if(!EnableChangeTracking || OrginalValues==null || !OrginalValues.Any()) 
      return new Dictionary<string, object>(); 

     // Only get properties that have changed. 
     var changedProperties = 
      this 
      .GetType() 
      .GetProperties() 
      .Where(p => !System.Attribute.IsDefined(p, typeof(IgnoreAttribute)) 
         && !Equals(p.GetValue(this, null), OrginalValues[p.Name])) 
      .ToDictionary(p => p.Name, p => p.GetValue(this)); 

     return changedProperties; 
    } 
+0

В вашем методе GetChanges, что означает «это»? Вы создали объект, который наследуется от словаря ? – Brandon

+0

** это ** относится к экземпляру MyObject, который наследует объект. Вы передаете объект, которому вы хотите присвоить значение свойства как параметр в GetValue. –

ответ

3

Поскольку ваш словарь <string, object>, != будет использовать ссылку сравнения. Используйте метод Equals для проверки значения. Это использует базовый Equals, который будет обрабатывать нулевые результаты для вас.

Where(p => !Equals(p.GetValue(this, null), OrginalValues[p.Name])) 
+0

Я знал об ошибке = = и равно, но когда я использовал p.GetValue (это, null) .Equals (originalValues ​​[p.Name]) Я получил исключение для ссылки на null. Я не знал о базовой Equals, действительно щедрой спасибо! Я обновил свой OP, чтобы показать законченный метод. –

+0

@JohnathonSullinger Рад, что это сработало. Можете ли вы пометить мой ответ как решение? – TTat

+0

Еще одна ошибка, которую я обнаружил, проверяя это. Он не возвращает никаких свойств, которые изменили их коллекции. Я могу понять, что он не обнаруживает изменения объекта в коллекции, но не должен ли он обнаруживать, что размер коллекции изменился по крайней мере? –

Смежные вопросы