linq C#记录的历史项列表,标识记录中确切的变量更改

cuxqih21  于 2023-09-28  发布在  C#
关注(0)|答案(4)|浏览(107)

所以我有一个表,我用cdc在sql中跟踪变化,我需要找到我的对象中的哪些特定值在给定时间内发生了变化。当我得到我的历史记录时,它基本上是一个从它改变的时间点开始的所有相同对象的列表。我需要一种有效的方法来使用这个列表来准确地识别对象内哪些字段发生了变化
我正在使用linq,但我很好奇是否有更好的方法?

Value01Changed = auditHistory.Any(x => 
         x.AuditAction == "Insert" || 
         auditHistory.Any(y => y.Value01 != x.Value01)),
  Value02Changed = auditHistory.Any(x => 
         x.AuditAction == "Insert" || 
         auditHistory.Any(y => y.Value02 != x.Value02)),
   Value03Changed = auditHistory.Any(x => 
         x.AuditAction == "Insert" || 
         auditHistory.Any(y => y.Value03 != x.Value03)),

为了清楚这个解决方案的作品,我只是认为这是昂贵和效率低下,我很好奇,如果有一个更好的方法

jm2pwxwz

jm2pwxwz1#

您可以只检查一次插入项,而不是每个值检查一次。

var itemWasInserted = auditHistory.Any(x => x.AuditAction == "Insert");

Value01Changed = itemWasInserted ||
         auditHistory.Any(x => auditHistory.Any(y => y.Value01 != x.Value01)),

Value01Changed = itemWasInserted || 
         auditHistory.Any(x => auditHistory.Any(y => y.Value02 != x.Value02)),

 //etc
rggaifut

rggaifut2#

基于Peter和John Wu的回答,我在一个扩展方法中实现了以下内容,它整理了我的代码并提高了性能

var hasInserts = auditHistory.Any(x => x.AuditAction == "Insert");

    Value01Changed = auditHistory.HasPropertyChanges(x => x.Value01 , hasInserts);

    Value02Changed = auditHistory.HasPropertyChanges(x => x.Value02, hasInserts);

    public static class HasPropertyChanged
    {
        public static bool HasPropertyChanges(this IEnumerable<AuditRecord> list, Func<AuditRecord, object> func,bool hasInserts)
        {
            if(hasInserts) return true;
            return list.GroupBy(func).Count() > 1;                
        }
    }
jvlzgdj9

jvlzgdj93#

首先,确保没有为每个Any往返数据库。将数据拉入内存。这样你只需要访问数据库一次。

var list = auditHistory.ToList();

确定属性是否有任何更改的简单方法是GroupBy。这可能会执行得稍微好一点,因为它只迭代列表一次,并使用哈希表来跟踪更改。

var value0changed = list.GroupBy( x => x.Value0 ).Count() > 1;

编辑

在阅读了this answer之后,我实际上建议你写一个像这样的扩展方法:

static public bool AllSame<T>(this Enumerable<T> source)
{
    var firstValue = source.First().Value;
    return source.All( x=> x.Value == firstValue );
}

然后像这样使用它:

var value0changed = list.AllSame();

这将更加高效。

hs1rzwqc

hs1rzwqc4#

似乎没有更好的方法,如果你使用一个功能,如时间表。
如果您将手动跟踪更改,则可以以(字段,新值,时间戳)的形式记录它们,这将直接提供所需的答案。

相关问题