Entity Framework Notes

1. Transaction

In all versions of Entity Framework, whenever you execute SaveChanges() to insert, update or delete on the database the framework will wrap that operation in a transaction. This transaction lasts only long enough to execute the operation and then completes. When you execute another such operation a new transaction is started.
Starting with EF6 Database.ExecuteSqlCommand() by default will wrap the command in a transaction if one was not already present. There are overloads of this method that allow you to override this behavior if you wish. Also in EF6 execution of stored procedures included in the model through APIs such as ObjectContext.ExecuteFunction() does the same (except that the default behavior cannot at the moment be overridden).
In either case, the isolation level of the transaction is whatever isolation level the database provider considers its default setting. By default, for instance, on SQL Server this is READ COMMITTED.
Entity Framework does not wrap queries in a transaction.

参考链接:https://msdn.microsoft.com/en-us/library/dn456843(v=vs.113).aspx

2. Interceptor

Registering interceptors via the config file is especially useful when you want to add logging to an existing application to help debug an issue. DatabaseLogger supports logging to a file by supplying the file name as a constructor parameter.

参考链接:https://blog.oneunicorn.com/2014/02/09/ef-6-1-turning-on-logging-without-recompiling/

    <interceptors>
      <interceptor type="System.Data.Entity.Infrastructure.Interception.DatabaseLogger, EntityFramework">
        <parameters>
          <parameter value="C:\MovieLibrary\MovieLibrary.Services\Log\EFInterceptor.log"/>
          <parameter value="true" type="System.Boolean"/>
        </parameters>
      </interceptor>
    </interceptors>

3. Concurrency

4. Performance

Disabling automatic detection of changes:

using (var context = new BloggingContext())
{
    try
    {
        context.Configuration.AutoDetectChangesEnabled = false;
        // Make many calls in a loop
        foreach (var blog in aLotOfBlogs)
        {
            context.Blogs.Add(blog);
        }
    }
    finally
    {
        context.Configuration.AutoDetectChangesEnabled = true;
    }
}

5. Connection String

6. Audit log of entity change

参考链接: https://www.exceptionnotfound.net/entity-change-tracking-using-dbcontext-in-entity-framework-6/

    public partial class MovieLibraryEntities
    {
        public override int SaveChanges()
        {
            List<DbEntityEntry> auditChanges = ChangeTracker.Entries().Where(x => x.State == EntityState.Modified || x.State == EntityState.Deleted).ToList();
            foreach (var item in auditChanges)
            {
                var primaryKeyValue = GetPrimaryKeyValue(item).ToString();
                var action = item.State == EntityState.Modified ? "Update" : "Delete";
                string tablename = item.Entity.GetType().Name;
                List<int?> result = SP_AddTableAuditLog(tablename, primaryKeyValue, action).ToList(); // Must apply ToList or ToArray to close the database reader before calling SaveChanges();
                if (result[0].HasValue && result[0].Value != 1)
                {
                    LoggerManager.DebugInfo.Debug(string.Format("Failed to add audit log:\r\nTable Name:{0}\r\nPrimary Key Value:{1}\r\nAction:{2}\r\nStored Procedure Return:{3}", tablename, primaryKeyValue, action, result[0].Value));
                }
            }
            return base.SaveChanges();
        }

        private object GetPrimaryKeyValue(DbEntityEntry entry)
        {
            var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
            return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
        }
    }

 

posted @ 2017-06-02 15:27  liangzi4000  阅读(185)  评论(0编辑  收藏  举报