【问题标题】:Log Each Changed Properties Into Database将每个更改的属性记录到数据库中
【发布时间】:2014-08-06 22:08:03
【问题描述】:

考虑在数据库中更新下面的类

public class ProductionLineItem
{
    public int Id { get; set; }
    public DateTime ProductionDate { get; set; }
    public string HandledBy { get; set; }
    public DateTime DateToMarket { get; set; }
}

void UpdateProductionRecord(ProductionLineItem existingRecord, ProductionLineItem modifiedRecord)
{
    existingRecord.Id = modifiedRecord.Id;
    existingRecord.ProductionDate = modifiedRecord.ProductionDate;
    existingRecord.HandledBy = modifiedRecord.HandledBy;
    existingRecord.DateToMarket = modifiedRecord.DateToMarket;
}

客户希望在专用表中记录所有更改属性。 我应该这样做:

void UpdateProductionRecordWithLog(ProductionLineItem existingRecord, ProductionLineItem modifiedRecord)
    {
        existingRecord.Id = modifiedRecord.Id;
        if (existingRecord.ProductionDate != modifiedRecord.ProductionDate)
        {
            existingRecord.ProductionDate = modifiedRecord.ProductionDate;
            //Log: productionDate update form xyz to abc
        }
        if (existingRecord.HandledBy != modifiedRecord.HandledBy)
        {
            existingRecord.HandledBy = modifiedRecord.HandledBy;
            //Log: HandledBy updated from Mr. John to Mr. Smith
        }
        if (existingRecord.DateToMarket != modifiedRecord.DateToMarket)
        {
            existingRecord.DateToMarket = modifiedRecord.DateToMarket;
            //Log: DateToMarket updated form 2013 to 2014
        }
    }

对于少量属性应该没问题,但如果属性超过 15-20。我认为这不是最好的方法。

我可以让我的代码更干净吗?如果需要,我愿意使用任何框架,如 AutoMapper 左右。

【问题讨论】:

    标签: c#


    【解决方案1】:

    有多种优雅的解决方案可以解决您的问题,其中包括:

    • 您可以使用面向方面的编程(AOP,对于框架,请参阅this answer)来捕获对属性的每次修改。您可以保存这些更改以供以后检索或调用随后记录的事件。
    • 您可以在这里很好地使用反射(例如PropertyInfo)并遍历所有属性并比较当前值。这将使您不必手动编写所有属性。
    • Reflection 和Attributes 连同需要记录的属性也可以工作。使用属性作为对需要记录的重要属性的一种便利贴。

    请注意,反射可能会带来一些性能损失。

    【讨论】:

      【解决方案2】:

      您使用实体框架吗?支持INotifypropertychanged,可以使用:

      How to raise an event on Property Change?

      如果不是,您的类可以自己实现 INotifyPropertyChanged() - 虽然不是很好(您必须显式编写 geteers / setter),但它提供了比直接在属性中调用登录工具更好的解耦(如果,如果您的日志记录不可用)。

      我会担心性能问题,所以我可能会存储日志并且偶尔只写一次......

      【讨论】:

        【解决方案3】:

        首先,您已经完成了比要求更多的工作,因为您只是在现有项目的属性不同时才更改它们。

        为您的课程添加一些新方法,例如LogDifferences(ProductLineItem old, ProductLineItem new) 并从 UpdateProductionItem 调用它会很好。

        就我个人而言,我会回到客户那里,说你真正想要做什么以及为什么,他们要求的更多是解决方案而不是要求。

        例如只需记录旧记录新记录,如数据库事务日志。分析需要时发生的变化。

        最后一种可能性,诚然可能会导致比它解决的问题更多的问题,就是将属性的值存储在 Dictionary<String,dynamic> 中,而不是离散成员中。

        那么基于Existing["ChangedToMarket"] = Modified["ChangedToMarket"] 记录更改是相当简单的。

        【讨论】:

        • 是的,当属性相等时,重新分配它们是没有意义的。
        • 不是我的意思。我是说记录更改并更改它是独立的功能。您可以在不记录的情况下进行更改,也可以在不更改的情况下进行记录。
        猜你喜欢
        • 1970-01-01
        • 2017-10-31
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-03
        • 1970-01-01
        相关资源
        最近更新 更多