EF6 中tracking log使用方法总结

先上一段最近项目中的代码,此代码可以放到自己项目中的dbContext中

public override Task<int> SaveChangesAsync()
        {
            List<AuditLog> AuditLogs = new List<AuditLog>();
            List<DataLensTrackingLog> trackinglogs = new List<DataLensTrackingLog>();
            var changeTracker = ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified);
            try
            {
                foreach (var entity in changeTracker)
                {
                    AuditLogs.Clear();
                    XmlDocument doc = new XmlDocument();
                    doc.AppendChild(doc.CreateElement(TrackingLog.Records));
                    if (entity.Entity != null)
                    {
                        var entityName = ObjectContext.GetObjectType(entity.Entity.GetType()).Name;
                        //string entityName = entity.Entity.GetType().Name;
                        EntityState state = entity.State;
                        switch (entity.State)
                        {
                            case EntityState.Modified:
                                //entityName = ObjectContext.GetObjectType(entity.Entity.GetType()).Name;
                                foreach (string prop in entity.OriginalValues.PropertyNames)
                                {
                                    object currentValue = entity.CurrentValues[prop];
                                    object originalValue = entity.GetDatabaseValues()[prop];//OriginalValues[prop];
                                    if (!Object.Equals(currentValue, originalValue)&&entity.Property(prop).IsModified==true
                                        &&prop.ToLower()!="lastupdateby")
                                    {
                                        AuditLogs.Add(new AuditLog
                                        {
                                            EntityName = entityName,
                                            RecordID = PrimaryKeyValue(entity),
                                            State = state,
                                            ColumnName = prop,
                                            OriginalValue = Convert.ToString(originalValue),
                                            NewValue = Convert.ToString(currentValue),
                                        });
                                    }
                                }
                                if (AuditLogs.Count > 0)
                                {
                                    TrackingLog.GetXmlForUpdate(doc, AuditLogs);
                                    trackinglogs.Add(new DataLensTrackingLog
                                    {
                                        EntityName = entityName,
                                        Email = this.Email,
                                        XmlDoc = CompressionHelper.Compresse("XmlDoc", new UTF8Encoding().GetBytes(doc.OuterXml)),
                                        CreateTime = DateTime.Now
                                    });
                                }
                                break;
                            case EntityState.Added:
                                //entityName = ObjectContext.GetObjectType(entity.Entity.GetType()).Name;
                                foreach (string prop in entity.CurrentValues.PropertyNames)
                                {
                                    AuditLogs.Add(new AuditLog
                                    {
                                        EntityName = entityName,
                                        RecordID = PrimaryKeyValue(entity),
                                        State = state,
                                        ColumnName = prop,
                                        OriginalValue = string.Empty,
                                        NewValue = entity.CurrentValues[prop],
                                    });

                                }
                                TrackingLog.GetXmlForUpdate(doc, AuditLogs);
                                trackinglogs.Add(new DataLensTrackingLog
                                {
                                    EntityName = entityName,
                                    Email = this.Email,
                                    XmlDoc = CompressionHelper.Compresse("XmlDoc", new UTF8Encoding().GetBytes(doc.OuterXml)),
                                    CreateTime = DateTime.Now
                                });
                                break;
                            case EntityState.Deleted:
                                //entityName = ObjectContext.GetObjectType(entity.Entity.GetType()).Name;
                                foreach (string prop in entity.OriginalValues.PropertyNames)
                                {
                                    AuditLogs.Add(new AuditLog
                                    {
                                        EntityName = entityName,
                                        RecordID = PrimaryKeyValue(entity),
                                        State = state,
                                        ColumnName = prop,
                                        OriginalValue = entity.OriginalValues[prop],
                                        NewValue = string.Empty,
                                    });

                                }
                                TrackingLog.GetXmlForUpdate(doc, AuditLogs);
                                trackinglogs.Add(new DataLensTrackingLog
                                {
                                    EntityName = entityName,
                                    Email = this.Email,
                                    XmlDoc = CompressionHelper.Compresse("XmlDoc", new UTF8Encoding().GetBytes(doc.OuterXml)),
                                    CreateTime = DateTime.Now
                                });
                                break;
                            default:
                                break;
                        }
                    }
                }
                DataTable dt=TypeConvert.ToDataTable(trackinglogs);
                SqlDataHelper.SqlBulkCopy(dt, "DataLensTrackingLog", DataBaseType.ConnLogDataStr);
                return base.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

EF6中可以覆写SaveChangesAsync(异步)或者SaveChanges来实现记录变化的跟踪,这其中包括新增、修改、和删除,
dbContext中的属性ChangeTracker可以跟踪属性的变化,即查找实体修改记录:ChangeTracker.Entries().Where(p => p.State ==EntityState.Modified);
查找新增的实体记录行:ChangeTracker.Entries().Where(p => p.State == EntityState.Added);查找删除的实体记录行:
ChangeTracker.Entries().Where(p => p.State == EntityState.Deleted)
     获取实体的名字是ObjectContext.GetObjectType(entity.Entity.GetType()).Name,之前获取实体是通过以下方式:
entity.Entity.GetType().Name,但是这种方式会有一个问题,假如说存在以下实体

public partial class DataLensDataPointUniverse
{
[Key]
public int DataPointUniverseId { get; set; }
public int DomicileId { get; set; }
public int ShareClassUniverseId { get; set; }
public int DataPointId { get; set; }
public int CollectionStatusId { get; set; }
public Nullable<System.DateTime> CollectionStartDate { get; set; }
public Nullable<System.DateTime> CollectionEndDate { get; set; }
public int CollectionFrequencyId { get; set; }
public int CollectionPriorityId { get; set; }
public string Restrictions { get; set; }
public int FundFormId { get; set; }
public string InterpretationRules { get; set; }
public string Comments { get; set; }
public string QualityMeasureCompleteness { get; set; }
public string QualityMeasureTimeliness { get; set; }
public string QualityMeasureAccuracy { get; set; }
public int FundCollectionRequirementId { get; set; }
public int LEANProjectId { get; set; }
public Nullable<System.Guid> CreateBy { get; set; }
public Nullable<System.Guid> LastUpdateBy { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public Nullable<System.DateTime> LastUpdateDate { get; set; }

public virtual DataLensDataPoint DataLensDataPoint { get; set; }
}

这时候获取的实体名字就可能是类似于这种格式343434343_DataLensDataPoint_3434,为什么会存在这种格式呢,因为

该实体中的DataPointId是另个属性 public virtual DataLensDataPoint DataLensDataPoint { get; set; }中的外键,即
(即实体DataLensDataPoint中DataPointId)

获取属性当前值entity.CurrentValues[prop](即还未保存到数据库),获取数据库当前值entity.GetDatabaseValues()[prop]
其中的entity.Property(prop).IsModified==true属性是来判断确实该值要存到数据库中,才要去记录日志,因为在Save
之前可能有些实体属性被标记为不做更改entity.Property(prop).IsModified==false;

获取实体主键的值可以用以下方法
private string PrimaryKeyValue(DbEntityEntry entry)
{
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
if (null == objectStateEntry.EntityKey.EntityKeyValues)
{
return string.Empty;
}
return string.Join(",", objectStateEntry.EntityKey.EntityKeyValues.Select(item => item.Value.ToString()).ToArray());
}

时间: 2024-10-14 04:06:45

EF6 中tracking log使用方法总结的相关文章

【翻译自mos文章】在Oracle GoldenGate中循环使用ggserr.log的方法

在OGG中循环使用ggserr.log的方法: 参考原文: OGG How Do I Recycle The "ggserr.log" File? (Doc ID 967932.1) 适用于: Oracle GoldenGate - Version 4.0.0 and later Generic Linux 问题 GoldenGate的 ggserr.log 日志文件包括有关 GoldenGate 事件的信息,比如:进程启动,关闭,error ,warning.该文件可能会变的很大.为

schema中的虚拟属性方法

schema中的虚拟属性方法相当于vue中的计算属性,它是通过已定义的schema属性的计算\组合\拼接得到的新的值 var personSchema = new Schema({ name: { first: String, last: String } }); var Person = mongoose.model('Person', personSchema); // create a document var bad = new Person({ name: { first: 'Walt

iOS5中UIViewController的新方法

iOS5中UIViewController的新方法 前言 在苹果的 WWDC2011 大会视频的<Session 101 - What’s New in Cocoa> 和<Session 102 - Implementing UIViewController Containment> 中介绍了苹果在 iOS5 中给 UIViewController 新增加的 5 方法以及一个属性: // 方法addChildViewController: removeFromParentViewC

Linux中LVM功能使用方法

1.介绍        LVM全称Logical Volume Manager(逻辑卷管理器),是将存储空间虚拟化成虚拟设备来进行管理的一种机制.LVM本身通过调用Linux内核中的"Device-mapper"功能来实现这种机制.         LVM组成部分: Physical volume(pv)物理卷:是LVM底层的设备,可以是硬盘分区,硬盘. Volume group (vg)卷组:是组织pv的管理单元. Logical volume(lv)逻辑卷:虚拟分区,既可以存储数据

Golang中使用log(一):Golang 标准库提供的Log

Golang的标准库提供了log的机制,但是该模块的功能较为简单(看似简单,其实他有他的设计思路).不过比手写fmt. Printxxx还是强很多的.至少在输出的位置做了线程安全的保护.其官方手册见Golang log (天朝的墙大家懂的).这里给出一个简单使用的例子: package main import ( "log" ) func main(){ log.Fatal("Come with fatal,exit with 1 \n") } 编译运行后,会看到程

JavaScript中Object.prototype.toString方法的原理

在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. ? 1 2 var arr = []; console.log(Object.prototype.toString.call(arr)) //"[object Array]" 本文要讲的就是,toString方法是如何做到这一点的,原理是什么. ECMAScript 3 在ES3中,Object.prototype.toString方法的规范如下:

详解Webwork中Action 调用的方法

详解Webwork中Action 调用的方法 从三方面介绍webwork action调用相关知识: 1.Webwork 获取和包装 web 参数 2.这部分框架类关系 3.DefaultActionProxyFactory.DefaultActionProxy.DefaultActionInvocation 终于要开始 webwork 核心业务类的总结,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork

Golang中使用log(二):Golang 标准库log的实现

前一篇文章我们看到了Golang标准库中log模块的使用,那么它是如何实现的呢?下面我从log.Logger开始逐步分析其实现. 其源码可以参考官方地址 1.Logger结构 首先来看下类型Logger的定义: type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix to write at beginning of each

Android.util.Log 关于Android开发中打印log

日常Android开发真机调试过程经常会遇到系统日志过多过快,想看的内容一闪而过的问题.而自定义些log可以很好的解决这些问题.   代码中添加 log  androidsdk中提供了log输出的api,方法在android.util.Log类中. Log.v(tag,message);        //verbose模式,打印最详细的日志 Log.d(tag,message);        //debug的日志 Log.i(tag,message);        //info的日志 Lo