如何将通用存储库、工作单元模式与多个数据库的多个 EDMX 一起使用



我正在开发一个有3个MS SQL Server数据库的项目。

我使用,

  • 实体框架 6.4.0,
  • 通用存储库,
  • 存储库工作单元模式。
  • ASP.Net MVC
  • 多个实体数据模型

我需要将更改作为一个事务保存到多个数据库中的多个表中(使用一种SaveChanges()方法(

我已经使用单个数据库,单个UoW类,单个通用存储库使用上述模式完成了项目。现在我被困在多个数据库上。

我的通用存储库类如下

public class GenericRepository<TEntity, TContext> : IGenericRepository<TEntity, TContext> 
where TEntity : class 
where TContext : DbContext
{
internal DbContext context;
internal DbSet<TEntity> dbSet;
public GenericRepository(DbContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}

public IEnumerable<TEntity> GetAll()
{
return context.Set<TEntity>().ToList();
}

public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetByID(object id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void InsertRange(IList<TEntity> entityList)
{
dbSet.AddRange(entityList);
}
public virtual void Delete(object id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void DeleteRange(IEnumerable<TEntity> lstEntity)
{
dbSet.RemoveRange(lstEntity);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
}

我的工作单元类如下;

public class UnitOfWork<TContext> : IDisposable where TContext : DbContext, new()
{
private DbContext context;
private IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_SIN, DbContext> tbl_Data_EmployeeData_sin;
public IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_SIN, DbContext> Tbl_Data_EmployeeData_sin
{
get
{
if (this.tbl_Data_EmployeeData_sin == null)
{
this.tbl_Data_EmployeeData_sin = new GenericRepository<TBL_RC_DATA_PHL_EmployeeData_SIN, DbContext>(context);
}
return tbl_Data_EmployeeData_sin;
}
}
private IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_PHL, DbContext> tbl_Data_EmployeeData_phl;
public IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_PHL, DbContext> Tbl_Data_EmployeeData_phl
{
get
{
if (this.tbl_Data_EmployeeData_phl == null)
{
this.tbl_Data_EmployeeData_phl = new GenericRepository<TBL_RC_DATA_PHL_EmployeeData_PHL, DbContext>(context);
}
return tbl_Data_EmployeeData_phl;
}
}
private IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_ENG, DbContext> tbl_Data_EmployeeData_eng;
public IGenericRepository<TBL_RC_DATA_PHL_EmployeeData_ENG, DbContext> Tbl_Data_EmployeeData_eng
{
get
{
if (this.tbl_Data_EmployeeData_eng == null)
{
this.tbl_Data_EmployeeData_eng = new GenericRepository<TBL_RC_DATA_PHL_EmployeeData_ENG, DbContext>(context);
}
return tbl_Data_EmployeeData_eng;
}
}
public UnitOfWork()
{
context = new TContext();
}
public void Save()
{
context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

我的服务图层类如下

public class svcEmployeeData
{
private UnitOfWork<DAL.RCPlusEntities> unitOfWork;
public svcEmployeeData()
{
unitOfWork = new UnitOfWork<DAL.RCPlusEntities>();
}
public void updateEmployees(TBL_RC_DATA_PHL_EmployeeData_SIN sin, TBL_RC_DATA_PHL_EmployeeData_ENG eng)
{
//updating Business Logic goes here
unitOfWork.Tbl_Data_EmployeeData_sin.Update(sin);        
unitOfWork.Tbl_Data_EmployeeData_eng.Update(eng);
unitOfWork.Save();
}
}

如何通过 3 个数据库将此体系结构转换为 3 个 EDMX...?

提前谢谢。

下面基于所有三个数据库的结构相同的假设。如果结构不同,我建议避免这种概括。相反,请为每个数据库维护不同的数据访问层。

您不能对其他数据库重用同一类的原因是,您正在UnitOfWork构造函数中创建DbContext实例,如下所示:

private DbContext context;
public UnitOfWork()
{
context = new TContext();
}

相反,如果您接受构造函数中的DbContext实例,我认为这同样适用于任何数据库。

private DbContext context;
public UnitOfWork(DbContext context)
{
this.context = context;
}

当然,此外,您需要更改服务层以注入正确的DbContext实例。

顺便说一下,在包装纸上使用太多包装器之前,请重新考虑。有关更多详细信息,请参阅此帖子。

现在,正如你所说:

我需要将更改作为一个事务保存到多个数据库中的多个表中(使用一个 SaveChanges(( 方法(

并评论说:

我需要处理交易。如果在更新第二个数据库表时发生任何错误,则应回滚第一个数据库表上的更改。使用一个UnitOwWork.Save((很容易做到

考虑@Holger在评论中提出的观点。

注意:SQL 服务器上的跨数据库事务仅在同一服务器上受支持。

SaveChanges方法在这里对您没有帮助。相反,您可以使用服务层中的TransactionScope跨数据库提交/回滚整个批处理。

因此,在服务层中,它如下所示:

using (TransactionScope scope = new TransactionScope())
{
//Create unitOfWorkDb1 here
unitOfWorkDb1.DoSomething();
unitOfWorkDb1.Save();
//Create unitOfWorkDb2 here
unitOfWorkDb2.DoSomething();
unitOfWorkDb2.Save();
scope.Complete();
}

请参考这篇和这篇关于交易范围的帖子。此外,本文内容丰富。

相关内容

最新更新