c# - 在C#中使用Lambda确定非相等属性值

标签 c# generics properties lambda propertyinfo

在我的应用程序中的某个时刻,我从数据库查询中获得了数据字典。我将数据和实例作为对象,然后调用RestoreState()方法,该方法采用数据字典并将值应用于新实例中的相应属性。

RestoreState()方法完成时,我然后将值的字典传递给对象到名为OriginalValues的属性中,如下所示:

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


稍后,用户通过UI对对象进行一些更改,然后按保存。然后,我想将对象属性的现有状态与原始状态进行比较,以便构造一个更新语句以发送到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,2014年1月1日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[8] {[DateInactivated,2014年1月1日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[9] {[EnteredBy,JS]} System.Collections.Generic.KeyValuePair
[10] {[日期输入,2014年1月1日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[11] {[CreatedBy,JS]} System.Collections.Generic.KeyValuePair
[12] {[UpdatedBy,JS]} System.Collections.Generic.KeyValuePair
[13] {[DateCreated,2014年1月21日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[14] {[DateUpdated,2014年1月21日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


我的Lambda表达式返回:


[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,2014年1月21日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[5] {[DateInactivated,2014年1月21日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[6] {[日期输入,2014年1月1日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[7] {[CreatedBy,SomeoneElse]} System.Collections.Generic.KeyValuePair
[8] {[DateCreated,2014年1月21日9:12:08 AM]} System.Collections.Generic.KeyValuePair
[9] {[DateUpdated,2014年1月21日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;
    } 

最佳答案

由于您的词典是<string, object>,因此!=将使用参考比较。使用Equals方法检查该值。这使用基本的Equals,它将为您处理空结果。

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

关于c# - 在C#中使用Lambda确定非相等属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21263457/

相关文章:

c# - 这两个单元测试断言有什么区别?

c# - objects.GetObject(i) 比 objects[i] 有什么优势?

c# - DateTime 到 Unix 时间转换不一致且 24 小时输入错误

c# - 从数组中只选择最好的项目

javascript - 使用 "Inspect Element"中的 ID 无法访问按钮

javascript - 如何将我的方法参数放入数组属性

spring - 库 jar 可以从 Spring Cloud Config Server 读取属性吗?

C# + 检查元组列表中的间隙和重叠

C# 将 Func<T, List<myClass>> 数组传递给方法

frameworks - 使用 Entity Framework 和 CaSTLe Windsor 容器解决通用存储库的问题