我正在使用mvc3网络应用程序。当用户更新某些内容时,我想将旧数据与用户正在输入的新数据进行比较,并针对每个不同的字段将其添加到日志中以创建活动日志。

现在,这是我的保存操作如下所示:

[HttpPost]
public RedirectToRouteResult SaveSingleEdit(CompLang newcomplang)
{
    var oldCompLang = _db.CompLangs.First(x => x.Id == newcomplang.Id);

    _db.CompLangs.Attach(oldCompLang);
    newcomplang.LastUpdate = DateTime.Today;
    _db.CompLangs.ApplyCurrentValues(newcomplang);
    _db.SaveChanges();

    var comp = _db.CompLangs.First(x => x.Id == newcomplang.Id);

    return RedirectToAction("ViewSingleEdit", comp);
}


我发现可以使用它来遍历oldCompLang的属性:

var oldpropertyInfos = oldCompLang.GetType().GetProperties();


但这并没有真正的帮助,因为它仅向我显示属性(Id,名称,状态...),而不显示这些属性的值(1,Hello,Ready ...)。

我可以走艰难的路:

if (oldCompLang.Status != newcomplang.Status)
{
    // Add to my activity log table something for this scenario
}


但是我真的不想对对象的所有属性都这样做。

我不确定迭代两个对象以查找不匹配项(例如,用户更改了名称或状态...)并根据可以存储在另一个表中的差异建立列表的最佳方法是什么。

最佳答案

还不错,您可以使用反射“手动”比较属性并编写扩展方法以进行重用-您可以以此为起点:

public static class MyExtensions
{
    public static IEnumerable<string> EnumeratePropertyDifferences<T>(this T obj1, T obj2)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        List<string> changes = new List<string>();

        foreach (PropertyInfo pi in properties)
        {
            object value1 = typeof(T).GetProperty(pi.Name).GetValue(obj1, null);
            object value2 = typeof(T).GetProperty(pi.Name).GetValue(obj2, null);

            if (value1 != value2 && (value1 == null || !value1.Equals(value2)))
            {
                changes.Add(string.Format("Property {0} changed from {1} to {2}", pi.Name, value1, value2));
            }
        }
        return changes;
    }
}

10-06 07:35