【问题标题】:Compare complex object and get difference C# .NET Core 3.1比较复杂对象并获得差异 C# .NET Core 3.1
【发布时间】:2020-06-01 13:35:46
【问题描述】:

我有两个 Profile 类的对象,我想比较它以获得差异。为了更好地解释:

    public partial class Profile
    {
        public long Id { get; set; }
        public long VisitorId { get; set; }
        public string Description { get; set; }
        public long Age { get; set; }
        public DateTime? LastUpdate { get; set;}
    }

我想在我的方法中了解对象oldProfilenewProfile 之间的区别以制作变更日志。

例如,如果oldProfileAge = 10Description = "old"newProfileAge = 11Description = "new",我现在将这个差异在我的数据库中进行两个不同的插入:

public void PostChangelogProfileDetail(Profile oldProfile, Profile newProfile)
{
    ProfileDetailChangeLog profileDetailChangeLog = new ProfileDetailChangeLog();

    //COMPARE oldProfile AND newProfile

    foreach ( //difference resulted in the compare)
    {
        profileDetailChangeLog.VisitorId = newProfile.VisitorId;
        profileDetailChangeLog.ModifiedRecord = //name of the attribute modified (Age, Description, etc...)

        _profileDetailChangeLog.Create(profileDetailChangeLog);
    }
}

【问题讨论】:

  • 比较对象有多种方法 1) 编写代码以逐个属性比较属性 2) 使用库;例如,您可以使用 Json 来查找使用 jsondiffpatch.net 的差异。检查这个答案 - stackoverflow.com/questions/24876082/…

标签: c# asp.net-core entity-framework-core compare


【解决方案1】:

当您调用AddUpdate 时,ef 核心返回EntityEntry。 从中EntityEntry,您可以通过OriginalValues(返回旧值)和CurrentValues(返回新值)属性获取当前值和旧值。

您可以通过反射比较和记录原始值和当前值的差异,以查看属性的类型/名称以及返回类型为 PropertyValues 的值。

【讨论】:

  • 感谢您的回答,我会记住这个提示。
  • 查看我的回答,了解您如何不必自己查询 CurrentValues。
【解决方案2】:

您可能希望使用关于它正在跟踪的对象的 EF Core 元数据来确定对它的更改。我自己在 .net core 3 中做了类似于 stackoverflow 解决方案的事情,这让我相信 3.1 也应该可以工作。

以下文章中有描述此方法的文章: Getting all changes made to an object in the Entity Framework & ChangeTracker in Entity Framework Core.

【讨论】:

  • 不知道这个东西,以后肯定会考虑这种方法。
【解决方案3】:

从 nugget 安装包 安装包 ObjectsComparer

然后暗示比较: var cmpr = 新的比较器(); /* 比较 isSame 是 booleab 变量,如果两个对象相同,则返回 true */ IEnumerable diff;

bool isSame = cmpr.Compare(obj1, obj2, out diff);

【讨论】:

  • 非常感谢,我看到了这个包,它非常适合我的需要。也可以免费使用吧?
  • 真的很喜欢这个框架,但如果你想更新你的数据库,它有点多余。
【解决方案4】:

对于断开连接的实体,我发现了这个solution

用于查找现有实体的更改:

var existing = context.Find<Item>(1);
if (existing != null) 
{ 
   context.Entry(existing).CurrentValues.SetValues(changed);
}

之后它的 EntityState 将是 Modified,但仅在实际发生变化的地方。

here 发布了相同的答案。

【讨论】:

    猜你喜欢
    • 2013-12-10
    • 1970-01-01
    • 2011-04-01
    • 2021-11-28
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 2016-01-18
    • 2011-06-24
    相关资源
    最近更新 更多