将每个更改的属性记录到数据库中

时间:2014-07-11 11:03:57

标签: c#

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

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这样的任何框架,如果需要的话。

3 个答案:

答案 0 :(得分:2)

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

  • 您可以使用面向方面编程(AOP,框架参见this answer)来捕获属性的每个修改。您可以保存这些更改以供以后检索或调用随后记录的事件。
  • 你可以在这里很好地使用Reflection(例如PropertyInfo)并迭代所有属性并比较当前值。这将使您无需手动编写所有属性。
  • 反射和Attributes以及需要记录的属性也将起作用。使用属性作为关于那些对于记录很重要的属性的便利贴。

请注意,Reflection可能会施加一些性能惩罚。

答案 1 :(得分:0)

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

How to raise an event on Property Change?

如果没有,你的类本身可以实现INotifyPropertyChanged() - 虽然不是很好(你必须明确地编写geteers / setter),它提供了比直接在属性中调用loggin工具更好的解耦(如果你的日志记录如果不可用)。

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

答案 2 :(得分:0)

首先,您所做的不仅仅是要求,因为您只更改现有项目的属性(如果它们不同)。

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

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

E.g。只记录旧记录新记录,就像数据库事务日志一样。分析在需要时发生了哪些变化。

最后的可能性,无可否认可能导致比解决更多的问题,是将属性的值存储在Dictionary<String,dynamic>而不是离散成员中。

然后根据Existing["ChangedToMarket"] = Modified["ChangedToMarket"]记录更改非常简单。