例外情况下的EF6日志数据库上下文

时间:2019-04-02 06:45:54

标签: c# entity-framework entity-framework-6 code-first

我使用EF 6已经有一段时间了,但是由于最近几周对它的需求,最近又出现了这个问题。

我有一个通用存储库类,可使用-Oracle.ManagedDataAccess与oracle plsql数据库进行通信。

该类具有CRUD操作,看起来像这样:

public class OracleGenericRepository<TEntity> where TEntity : class
{
    #region Private member variables...
    internal OracleRefundsContext Context;
    internal DbSet<TEntity> DbSet;
    #endregion

    #region Public Constructor...
    /// <summary>
    /// Public Constructor,initializes privately declared local variables.
    /// </summary>
    /// <param name="context"></param>
    public OracleGenericRepository(OracleRefundsContext context)
    {
        this.Context = context;
        this.DbSet = context.Set<TEntity>();
    }
    #endregion

    #region Async member methods...
    /// <summary>
    /// generic GetById async method for Entities
    /// </summary>
    /// <returns>TEntity</returns>
    public virtual async Task<TEntity> GetByIdAsync(int id)
    {
        return await DbSet.FindAsync(id);
    }

    /// <summary>
    /// generic get method , fetches data for the entities on the basis of condition.
    /// </summary>
    /// <param name="predicate">where</param>
    /// <returns>TEntity</returns>
    public virtual async Task<TEntity> GetAsync(System.Linq.Expressions.Expression<Func<TEntity,bool>> predicate)
    {
        return await DbSet.FirstAsync(predicate);
    }

    /// <summary>
    /// generic method to get many record on the basis of a condition.
    /// </summary>
    /// <param name="predicate">where</param>
    /// <returns>IEnumerable<TEntity></returns>
    public virtual async Task<IEnumerable<TEntity>> GetManyAsync(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate)
    {
        return await DbSet.Where(predicate).ToListAsync<TEntity>();
    }
    #endregion

    #region Public member methods...

    /// <summary>
    /// generic Get method for Entities
    /// </summary>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> Get()
    {
        IQueryable<TEntity> query = DbSet;
        return query.ToList();
    }

    /// <summary>
    /// Generic get method on the basis of id for Entities.
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public virtual TEntity GetByID(object id)
    {
        return DbSet.Find(id);
    }

    /// <summary>
    /// generic Insert method for the entities
    /// </summary>
    /// <param name="entity"></param>
    public virtual void Insert(TEntity entity)
    {
        DbSet.Add(entity);   
    }

    /// <summary>
    /// Generic Delete method for the entities
    /// </summary>
    /// <param name="id"></param>
    public virtual void Delete(object id)
    {
        TEntity entityToDelete = DbSet.Find(id);
        Delete(entityToDelete);
    }

    /// <summary>
    /// Generic Delete method for the entities
    /// </summary>
    /// <param name="entityToDelete"></param>
    public virtual void Delete(TEntity entityToDelete)
    {
        if (Context.Entry(entityToDelete).State == EntityState.Detached)
        {
            DbSet.Attach(entityToDelete);
        }
        DbSet.Remove(entityToDelete);
    }

    /// <summary>
    /// Generic update method for the entities
    /// </summary>
    /// <param name="entityToUpdate"></param>
    public virtual void Update(TEntity entityToUpdate)
    {
        DbSet.Attach(entityToUpdate);
        //Context.Entry(entityToUpdate).State = EntityState.Modified;

        //Ensure only modified fields are updated. - updated by Natalia Gordon at 17/12/2017
        var dbEntityEntry = Context.Entry(entityToUpdate);
        foreach (var property in dbEntityEntry.OriginalValues.PropertyNames)
        {
            var original = dbEntityEntry.OriginalValues.GetValue<object>(property);
            var current = dbEntityEntry.CurrentValues.GetValue<object>(property);
            if (original != null && !original.Equals(current))
                dbEntityEntry.Property(property).IsModified = true;
        }
    }

    /// <summary>
    /// generic method to get many record on the basis of a condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> GetMany(Func<TEntity, bool> where)
    {
        return DbSet.Where(where).ToList();
    }

    /// <summary>
    /// generic method to get many record on the basis of a condition but query able.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public virtual IQueryable<TEntity> GetManyQueryable(Func<TEntity, bool> where)
    {
        return DbSet.Where(where).AsQueryable();
    }

    /// <summary>
    /// generic get method , fetches data for the entities on the basis of condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public TEntity Get(Func<TEntity, Boolean> where)
    {
        return DbSet.Where(where).FirstOrDefault<TEntity>();
    }

    /// <summary>
    /// generic delete method , deletes data for the entities on the basis of condition.
    /// </summary>
    /// <param name="where"></param>
    /// <returns></returns>
    public void Delete(Func<TEntity, Boolean> where)
    {
        IQueryable<TEntity> objects = DbSet.Where<TEntity>(where).AsQueryable();
        foreach (TEntity obj in objects)
            DbSet.Remove(obj);
    }

    /// <summary>
    /// generic method to fetch all the records from db
    /// </summary>
    /// <returns></returns>
    public virtual IEnumerable<TEntity> GetAll()
    {
        return DbSet.ToList();
    }

    /// <summary>
    /// Inclue multiple
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="include"></param>
    /// <returns></returns>
    public IQueryable<TEntity> GetWithInclude(
        System.Linq.Expressions.Expression<Func<TEntity,
        bool>> predicate, params string[] include)
    {
        IQueryable<TEntity> query = this.DbSet;
        query = include.Aggregate(query, (current, inc) => current.Include(inc));
        return query.Where(predicate);
    }

    /// <summary>
    /// Generic method to check if entity exists
    /// </summary>
    /// <param name="primaryKey"></param>
    /// <returns></returns>
    public bool Exists(object primaryKey)
    {
        return DbSet.Find(primaryKey) != null;
    }

    /// <summary>
    /// Gets a single record by the specified criteria (usually the unique identifier)
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record that matches the specified criteria</returns>
    public TEntity GetSingle(Func<TEntity, bool> predicate)
    {
        return DbSet.Single<TEntity>(predicate);
    }

    /// <summary>
    /// The first record matching the specified criteria
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record containing the first record matching the specified criteria</returns>
    public TEntity GetFirst(Func<TEntity, bool> predicate)
    {
        return DbSet.First<TEntity>(predicate);
    }

    public IEnumerable<TEntity> ExecWithStoreProcedure(string query, params object[] parameters)
    {
        return DbSet.SqlQuery(query, parameters);

    }

    #endregion

}

我有一个看起来像这样的工作单元,我将发布有趣的部分:

        public void Save()
        {        
            try
            {
                _context.Database.Log = s => { WriteInfo($"Trying to execute command:{s}"); }; 
                _context.SaveChanges();
            }            
            catch (Exception ex)
            {

                DbUpdateException dbException = ex as DbUpdateException;
                if (dbException != null)
                {
                    Exception ineer = ex;
                    while (ineer.InnerException != null)
                    {
                        ineer = ineer.InnerException;
                    }

                    throw ineer;
                }
                else
                {
                    throw;
                }
            }
        }

问题是,_context.Database.Log正在被调用SaveChanges()。 我只想记录日志,除非发生异常,因为我不想创建巨大的日志文件。

有什么方法可以仅在例外情况下创建_context.Database.Log的日志记录,无需再次调用SaveChanges()

0 个答案:

没有答案