gpt4 book ai didi

c# - 如何使用通用存储库、工作单元模式和多个数据库的多个 EDMX

转载 作者:太空宇宙 更新时间:2023-11-03 11:56:51 25 4
gpt4 key购买 nike

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

我用,

  • Entity Framework 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;
}

当然,您还需要更改服务层以注入(inject)正确的 DbContext 实例。

顺便说一句,在 wrapper 上使用过多的 wrapper 之前请重新考虑一下。请引用this发布更多详细信息。

现在,正如你所说:

I need to save changes into multiple tables in multiple DBs as one transaction (Using one SaveChanges() method)

并评论道:

I need to handle transactions. If any error occurred when updating the 2nd DB table, Changes on 1st DB tables should be rolled back. Easy to do it with one UnitOwWork.Save()

考虑@Holger 在 comment 中提出的观点.

Note: Cross-Database Transactions on SQL-Server are only supported on the same server. – Holger

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

所以,在服务层,它看起来像下面这样:

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

//Create unitOfWorkDb2 here
unitOfWorkDb2.DoSomething();
unitOfWorkDb2.Save();

scope.Complete();
}

请引用thisthis关于交易范围的帖子。另外,this文章内容丰富。

关于c# - 如何使用通用存储库、工作单元模式和多个数据库的多个 EDMX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59245998/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com