Live Traffic Feed

Showing posts with label Track changes in entity framework. Show all posts
Showing posts with label Track changes in entity framework. Show all posts

Monday, March 19, 2018

Manage Audit using DbContext in Entity Framework 6

Leave a Comment
Create table in sql server (AuditMaster):
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [AuditMaster](
       [AuditId] [int] IDENTITY(1,1) NOT NULL,
       [TableName] [nvarchar](100) NOT NULL, -- for table name
       [PrimaryKeyValues] [nvarchar](100) NOT NULL, -- for identity value of affected table
       [Description] [nvarchar](max) NOT NULL, -- store one string here for track changes in record
       [UserId] [int] NOT NULL, -- store user information who affect that row
       [CreatedDate] [datetime] NOT NULL, -- time tracking purpose
 CONSTRAINT [PK_AuditMaster] PRIMARY KEY CLUSTERED
(
       [AuditId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO


Create class which is partial class of yourdbcontext class:
public partial class YourDbContextClass : Microsoft.EntityFrameworkCore.DbContext
    {
        object GetPrimaryKeyValue(EntityEntry entry)
        {
            foreach (var property in entry.Properties)
            {
                if (property.Metadata.IsPrimaryKey())
                {
                    return property.CurrentValue;
                }
            }
            //var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
            //return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
            return new object();
        }
        public virtual int SaveChanges(int? objUSerId)
        {
            try
            {

                var changeTrack = ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified).ToList();
                foreach (var entry in changeTrack)
                {
                    if (entry.Entity != null)
                    {
                        string entityName = string.Empty;
                        string state = string.Empty;
                        var now = DateTime.UtcNow;
                        String Description = string.Empty;
                        //LogMaster log = new LogMaster();

                        switch (entry.State)
                        {
                            case EntityState.Modified:
                                entityName = entry.Entity.GetType().Name;
                                var primaryKey = GetPrimaryKeyValue(entry);
                                //foreach (var prop in entry.OriginalValues.PropertyNames)
                                foreach (var prop in entry.OriginalValues.Properties)
                                {
                                    String originalValue = Convert.ToString(entry.GetDatabaseValues().GetValue<object>(prop));
                                    String currentValue = Convert.ToString(entry.CurrentValues[prop]);
                                    if (originalValue != currentValue)
                                    {
                                        if (currentValue == "False" && prop.PropertyInfo.Name == "IsActive")
                                        {
                                            AuditMaster logDeleted = new AuditMaster()
                                            {
                                                TableName = entityName,
                                                Description = "Delete Record",
                                                PrimaryKeyValues = GetPrimaryKeyValue(entry).ToString(),
                                                UserId = (int)objUSerId,
                                                CreatedDate = now
                                            };
                                            AuditMaster.Add(logDeleted);
                                        }
                                        else
                                        {
                                            Description += prop.Name + ":" + Convert.ToString(originalValue) + " -> " + Convert.ToString(currentValue) + ",";
                                        }
                                    }
                                }
                                if (!string.IsNullOrEmpty(Description))
                                {
                                    AuditMaster log = new AuditMaster()
                                    {
                                        TableName = entityName,
                                        Description = !string.IsNullOrEmpty(Description) ? Description.Remove(Description.Length - 1) : "",
                                        PrimaryKeyValues = primaryKey.ToString(),
                                        UserId = (int)objUSerId,
                                        CreatedDate = now
                                    };

                                    AuditMaster.Add(log);
                                }
                                break;
                            case EntityState.Added:
                                entityName = entry.Entity.GetType().Name;
                                foreach (var prop in entry.OriginalValues.Properties)
                                {
                                    String currentValue = Convert.ToString(entry.CurrentValues[prop]);
                                    Description += prop.Name + ":" + Convert.ToString(currentValue) + ",";
                                }
                                AuditMaster logAdd = new AuditMaster()
                                {
                                    TableName = entityName,
                                    Description = "Add Record->" + Description,
                                    PrimaryKeyValues = "0",
                                    UserId = (int)objUSerId,
                                    CreatedDate = now
                                };
                                AuditMaster.Add(logAdd);
                                break;
                            case EntityState.Deleted:
                                entityName = entry.Entity.GetType().Name;
                                AuditMaster logDelete = new AuditMaster()
                                {
                                    TableName = entityName,
                                    Description = "Delete Record",
                                    PrimaryKeyValues = GetPrimaryKeyValue(entry).ToString(),
                                    UserId = (int)objUSerId,
                                    CreatedDate = now
                                };
                                AuditMaster.Add(logDelete);
                                break;
                            default:
                                break;
                        }
                        //LogMasters.Add(log);
                    }
                }
                return base.SaveChanges();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        public virtual async Task<int> SaveChangesAsync(int? objUSerId)
        {
            try
            {
                var changeTrack = ChangeTracker.Entries().Where(p => p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified).ToList();
                foreach (var entry in changeTrack)
                {
                    if (entry.Entity != null)
                    {
                        string entityName = string.Empty;
                        string state = string.Empty;
                        var now = DateTime.UtcNow;
                        String Description = string.Empty;
                        //LogMaster log = new LogMaster();

                        switch (entry.State)
                        {
                            case EntityState.Modified:
                                entityName = entry.Entity.GetType().Name;
                                var primaryKey = GetPrimaryKeyValue(entry);
                                //foreach (var prop in entry.OriginalValues.PropertyNames)
                                foreach (var prop in entry.OriginalValues.Properties)
                                {
                                    String originalValue = Convert.ToString(entry.GetDatabaseValues().GetValue<object>(prop));
                                    String currentValue = Convert.ToString(entry.CurrentValues[prop]);
                                    if (originalValue != currentValue)
                                    {
                                        if (currentValue == "False" && prop.PropertyInfo.Name == "IsActive")
                                        {
                                            AuditMaster logDeleted = new AuditMaster()
                                            {
                                                TableName = entityName,
                                                Description = "Delete Record",
                                                PrimaryKeyValues = GetPrimaryKeyValue(entry).ToString(),
                                                UserId = (int)objUSerId,
                                                CreatedDate = now
                                            };
                                            await AuditMaster.AddAsync(logDeleted);
                                        }
                                        else
                                        {
                                            Description += prop.Name + ":" + Convert.ToString(originalValue) + " -> " + Convert.ToString(currentValue) + ",";

                                        }
                                    }
                                }
                                if (!string.IsNullOrEmpty(Description))
                                {
                                    AuditMaster log = new AuditMaster()
                                    {
                                        TableName = entityName,
                                        Description = !string.IsNullOrEmpty(Description) ? Description.Remove(Description.Length - 1) : "",
                                        PrimaryKeyValues = primaryKey.ToString(),
                                        UserId = (int)objUSerId,
                                        CreatedDate = now
                                    };

                                    await AuditMaster.AddAsync(log);
                                }
                                break;
                            case EntityState.Added:
                                entityName = entry.Entity.GetType().Name;
                                foreach (var prop in entry.OriginalValues.Properties)
                                {
                                    String currentValue = Convert.ToString(entry.CurrentValues[prop]);
                                    Description += prop.Name + ":" + Convert.ToString(currentValue) + ",";
                                }
                                AuditMaster logAdd = new AuditMaster()
                                {
                                    TableName = entityName,
                                    Description = "Add Record->" + Description,
                                    PrimaryKeyValues = "0",
                                    UserId = (int)objUSerId,
                                    CreatedDate = now
                                };
                                await AuditMaster.AddAsync(logAdd);
                                break;
                            case EntityState.Deleted:
                                entityName = entry.Entity.GetType().Name;
                                AuditMaster logDelete = new AuditMaster()
                                {
                                    TableName = entityName,
                                    Description = "Delete Record",
                                    PrimaryKeyValues = GetPrimaryKeyValue(entry).ToString(),
                                    UserId = (int)objUSerId,
                                    CreatedDate = now
                                };
                                await AuditMaster.AddAsync(logDelete);
                                break;
                            default:
                                break;
                        }
                        //LogMasters.Add(log);
                    }
                }
                return await base.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                throw;
            }
        }  
    }


Now if you want to save any records in database then you need to write .savechanges(userid) or .savechanges().


It will track all records which are updated/added/deleted from entity framework.
Read More