我使用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()
?