【发布时间】:2015-03-23 21:39:53
【问题描述】:
我在stackoverflow上搜索但找不到类似的问题,如果已经有请指出。
我试图实现一个具有同步和异步操作的通用可重用存储库,但我对实体框架和工作单元知之甚少,我正在努力寻找实现它的正确方法。
我在 SaveAndCommit 操作上添加了一些变体,但不知道使用事务和异步执行此操作的最佳方法是什么。
----编辑----
据我了解,在执行多个操作时应使用事务,但出于理解目的,我将其用于一项操作。 (如有错误请指正)
这是我到目前为止所做的
public class Service<TEntity> : IService<TEntity>
where TEntity : Entity
{
#region Constructor and Properties
UnitOfWork _unitOfWork { get { return UnitOfWork.UnitOfWorkPerHttpRequest; } }
protected DbSet<TEntity> Entities
{
get { return _unitOfWork.Set<TEntity>(); }
}
#endregion Constructor and Properties
#region Operations
public virtual IQueryable<TEntity> QueryableEntities()
{
return Entities;
}
public virtual async Task<IList<TEntity>> WhereAsync(Expression<Func<TEntity, bool>> predicate)
{
return await Entities.Where(predicate).ToListAsync();
}
public virtual IList<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
{
return Entities.Where(predicate).ToList();
}
public virtual async Task<TEntity> FirstOrDefaultAsync(Expression<Func<TEntity, bool>> predicate)
{
return await Entities.FirstOrDefaultAsync(predicate);
}
public virtual TEntity FirstOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return Entities.FirstOrDefault(predicate);
}
public virtual async Task<TEntity> GetByIdAsync(int id)
{
return await Entities.FindAsync(id);
}
public virtual TEntity GetById(int id)
{
return Entities.Find(id);
}
// Method to the change the EntityState
public virtual void Save(TEntity entity)
{
if (entity.Id == 0)
{
Entities.Add(entity);
}
else
{
_unitOfWork.Entry(entity).State = EntityState.Modified;
}
}
#region Need clarification here
// Uses transaction scope to commit the entity and dispose automatically
// call rollback but this is not async and don't have any async
// functions (Or I could not find)
public virtual void SaveAndCommit(TEntity entity)
{
using (var transaction = _unitOfWork.BeginTransaction())
{
try
{
Save(entity);
transaction.Commit();
}
catch (DbEntityValidationException e)
{
}
}
}
// This is asynchronous but don't uses transaction
public virtual async Task SaveAndCommitAsync(TEntity entity)
{
try
{
Save(entity);
await _unitOfWork.SaveChangesAsync();
}
catch (DbEntityValidationException e)
{
}
}
// Tried to mix async and transaction but don't know if it will actually
// work or correct way of doing this
public virtual async Task SaveAndCommitWithTransactionAsync(TEntity entity)
{
using (var transaction = _unitOfWork.BeginTransaction())
{
try
{
Save(entity);
await _unitOfWork.SaveChangesAsync();
}
catch (DbEntityValidationException e)
{
transaction.Rollback();
}
}
}
#endregion Need clarification here
public virtual async Task DeleteAsync(TEntity entity)
{
if (entity == null) return;
Entities.Remove(entity);
await _unitOfWork.SaveChangesAsync();
}
//All similar methods for delete as for Save
public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> predicate = null)
{
if (predicate != null)
{
return await Entities.CountAsync(predicate);
}
return await Entities.CountAsync();
}
#endregion Operations
}
请指导我并建议实现此目标的最佳方法。
现在看来,使用异步调用实现事务范围的正确方法是
public virtual async Task SaveAndCommitWithTransactionAsync(TEntity entity)
{
using (var transaction = _unitOfWork.BeginTransaction())
{
Save(entity);
await _unitOfWork.SaveChangesAsync();
// Still no changes made to database
transaction.Commit();
//Rollback will automatically be called by using in dispose method
}
}
参考资料 MSDN Reference
Blog with more clear description
visualstudiomagazine.com 对于:当您调用 SaveChanges 时,您的任何更改都不会生效,直到您调用 Transaction 对象的 Commit 方法
【问题讨论】:
-
似乎是什么问题?您的问题不清楚
-
从我的问题:“我正在努力寻找正确的方法来实现它”我无法弄清楚如何将服务与工作单元和异步保存或删除操作一起使用。
标签: c# .net entity-framework async-await transactionscope