Определение не равных значений свойств с помощью лямбды в C#
В какой-то момент моего приложения мне предоставляют словарь данных из запроса к базе данных. Я беру эти данные и экземпляр объекта и вызываю RestoreState()
метод, который берет словарь данных и применяет значения к соответствующим свойствам в новом экземпляре.
Когда RestoreState()
метод завершен, я затем передаю словарь значений объекту в свойство с именем OriginalValues
вроде такой:
myObject.EnableChangeTracking = true;
myObject.OrginalValues = dictionaryData;
Позже пользователь вносит некоторые изменения в объект через пользовательский интерфейс и нажимает сохранить. Затем я хочу сравнить существующее состояние свойств объектов с исходным состоянием, чтобы можно было создать оператор обновления для отправки в SQL.
Проблема (и вопрос) в том, что мое лямбда-выражение для сравнения моего текущего значения свойства со значением в словаре не работает. 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] {[DateActivation, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [8] {[DateInactivation, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [9] {[EnteredBy, JS]} System.Collections.Generic.KeyValuePair
- [10] {[DateEntered, 21.01.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, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [14] {[DateUpdated, 21.01.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, False]} System.Collections.Generic.KeyValuePair
- [21] {[IsValid, False]} 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] {[DateActivation, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [5] {[DateInactivation, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [6] {[DateEntered, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [7] {[CreatedBy, SomeoneElse]} System.Collections.Generic.KeyValuePair
- [8] {[DateCreated, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [9] {[DateUpdated, 21.01.2014 9:12:08 AM]} System.Collections.Generic.KeyValuePair
- [10] {[IsActive, True]} System.Collections.Generic.KeyValuePair
- [11] {[EnableChangeTracking, True]} System.Collections.Generic.KeyValuePair
- [12] {[IsValid, False]} System.Collections.Generic.KeyValuePair
- [13] {[OrginalValues, System.Collections.Generic.Dictionary`2 [System.String, System.Object]]} System.Collections.Generic.KeyValuePair
Единственными свойствами, которые я изменил в моем модульном тесте, были OrgNumber и CreatedBy. У кого-нибудь есть идеи?
Обновить
Ниже приведен код, который я использую, чтобы обновить свойства, а затем вызвать GetChanges()
метод.
myObject.OrgNumber = "2222";
myObject.CreatedBy = "SomeoneElse";
myDictionary = myObject.GetChanges();
Обновление 2
Мне любопытно, если проблема в том, что мой словарь <string, object>
а я сравниваю как с ссылочными, так и с не ссылочными типами? Значит, значение int сравнивается с объектом и возвращается? Я не знаю.
Обновление 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;
}
1 ответ
Так как ваш словарь <string, object>
, !=
будет использовать сравнение ссылок. Использовать Equals
способ проверить значение. При этом используется базовое равенство, которое будет обрабатывать для вас нулевые результаты.
Where(p => !Equals(p.GetValue(this, null), OrginalValues[p.Name]))