asp.net mvc 中 entity framework 的存储库模式和工作单元对应用程序性能的影响
Effect in application performance by Repository pattern and Unit of work with entity framework in asp.net mvc
我正在使用一个数据库,其中我有超过 75 个 tables,并且我在一个 ASP.NET MVC 项目中使用 Entity Framework 的存储库和工作单元模式。我有点困惑,心里对对象创建有些疑问。当 UnitOfWork 初始化时,它会为 UnitOfWork 中存在的所有 table 实体创建对象。因此应用程序负载可能很重。
工作单元界面如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Application.Repository;
using Application.Repository.General;
namespace Application.UnitOfWorks
{
public interface IUnitOfWork : IDisposable
{
IGeneralRegionMasterRepository GeneralRegionMasters { get; }
IGeneralSubRegionMasterRepository GeneralSubRegionMasters { get; }
IGeneralCountryMasterRepository GeneralCountryMasters { get; }
IGeneralStateMasterRepository GeneralStateMasters { get; }
IGeneralCityMasterRepository GeneralCityMasters { get; }
int Complete();
}
}
实施:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Application.EntityFramework;
using Application.Repository;
using Application.Repository.General;
namespace Application.UnitOfWorks
{
public class UnitOfWork : IUnitOfWork
{
public readonly InventoryDbContext _context;
public UnitOfWork(InventoryDbContext context)
{
_context = context;
GeneralRegionMasters = new GeneralRegionMasterRepository(_context);
GeneralSubRegionMasters = new GeneralSubRegionMasterRepository(_context);
GeneralCountryMasters = new GeneralCountryMasterRepository(_context);
GeneralStateMasters = new GeneralStateMasterRepository(_context);
GeneralCityMasters = new GeneralCityMasterRepository(_context);
}
public IGeneralRegionMasterRepository GeneralRegionMasters { get; private set; }
public IGeneralSubRegionMasterRepository GeneralSubRegionMasters { get; private set; }
public IGeneralCountryMasterRepository GeneralCountryMasters { get; private set; }
public IGeneralStateMasterRepository GeneralStateMasters { get; private set; }
public IGeneralCityMasterRepository GeneralCityMasters { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
}
我想知道它对应用程序的性能影响。预先感谢您的帮助。
我 运行 遇到了您过去描述的相同问题。代码的结构让人感觉非常沉重,因为您正在创建 70 个存储库的新实例,即使您可能只需要其中一个。这就是为什么我刚刚开始避免在直接使用 EF 时添加自己的 UoW 和 Repositories,因为 EF 已经内置了 Repositories 和 UoW(DbSets = Repos,Save Changes 会在所有 DbSet 更改结束时保存 UoW)。如果您不想直接针对 DbContext 进行编码,只需让您的 DbContext 直接实现 IUnitOfWork 接口,然后就可以了。还要在该 UnitOfWork 上公开所有 DbSet。然后你可以让它也实现 IMyDbContext 并让它公开 DbSets 并让这个接口也实现 IUnitOfWork(或者有 DbContext - > IMyDbContext - > IUnitOfWork)或者如果你不希望回购代码可以访问保存在底部。这最终使长 运行 变得更容易。无需维护奇怪的代码,无需创建 类。如果您切换到不使用 EF,您仍然可以在幕后使用那些相同的接口,唯一需要更改的是 DbSet 实现(也许您甚至可以将其设为通用 - 在 DbSet 上创建实现另一个的接口界面也一样)。就个人而言,我正在走 CQS 道路,所以我不必再担心回购或 UoW。 :)
编辑
尽我所能! :)
public interface IUnitOfWork
{
int Complete();
Task<int> CompleteAsync();
}
public interface IInventoryDbContext : IUnitOfWork
{
DbSet<GeneralRegionMaster> GeneralRegionMasters { get; }
DbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; }
... etc
}
public class MyDbContext : DbContext, IInventoryDbContext
{
public DbSet<GeneralRegionMaster> GeneralRegionMasters { get; set; }
public DbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; set;
}
public int Complete() => this.SaveChanges();
public Task<int> CompleteAsync() => this.SaveChangesAsync();
}
如果你只做了控制器关卡:
public class MyController : Controller
{
private readonly IInventoryDbContext _context;
public MyController(IInventoryDbContext context)
{
_context = context;
}
public JsonResult CreateGeneralRegionMaster(GeneralRegionMaster entity)
{
_context.GeneralRegionMaster.Add(entity);
var result = _context.Complete();
return Json(result == 1);
}
}
同样,您可以对 DbSet 做一些不同的事情,而是这样做:
public interface IRepo<T> where T: class
{
// Expose whatever methods you want here
}
public class MyDbSet<T> : DbSet<T>, IRepo<T> where T: class
{
}
然后这个改变:
public interface IInventoryDbContext : IUnitOfWork
{
IRepo<GeneralRegionMaster> GeneralRegionMasters { get; }
IRepo<GeneralSubRegionMaster> GeneralSubRegionMasters { get; }
... etc
}
public class MyDbContext : DbContext, IInventoryDbContext
{
public MyDbSet<GeneralRegionMaster> GeneralRegionMasters { get; set; }
public MyDbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; set; }
public IRepo<GeneralRegionMaster> GeneralRegionMastersRepo => GeneralRegionMasters;
public IRepo<GeneralSubRegionMaster> GeneralSubRegionMastersRepo => GeneralSubRegionMasters;
public int Complete() => this.SaveChanges();
public Task<int> CompleteAsync() => this.SaveChangesAsync();
}
回复:
When UnitOfWork initializes, it creates object for all table's entity which is present in UnitOfWork. So it can be heavy for application load.
您不需要在 UoW 构造函数中初始化所有的 repo 实例。
您可以在相应的getter中需要它们时创建它们(延迟初始化):
private IGeneralRegionMasterRepository _generalRegionMasters;
public IGeneralRegionMasterRepository GeneralRegionMasters {
get {
if (_generalRegionMasters == null) {
_generalRegionMasters = new GeneralRegionMasterRepository(_context);
}
return _generalRegionMasters;
}
}
我正在使用一个数据库,其中我有超过 75 个 tables,并且我在一个 ASP.NET MVC 项目中使用 Entity Framework 的存储库和工作单元模式。我有点困惑,心里对对象创建有些疑问。当 UnitOfWork 初始化时,它会为 UnitOfWork 中存在的所有 table 实体创建对象。因此应用程序负载可能很重。
工作单元界面如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Application.Repository;
using Application.Repository.General;
namespace Application.UnitOfWorks
{
public interface IUnitOfWork : IDisposable
{
IGeneralRegionMasterRepository GeneralRegionMasters { get; }
IGeneralSubRegionMasterRepository GeneralSubRegionMasters { get; }
IGeneralCountryMasterRepository GeneralCountryMasters { get; }
IGeneralStateMasterRepository GeneralStateMasters { get; }
IGeneralCityMasterRepository GeneralCityMasters { get; }
int Complete();
}
}
实施:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Application.EntityFramework;
using Application.Repository;
using Application.Repository.General;
namespace Application.UnitOfWorks
{
public class UnitOfWork : IUnitOfWork
{
public readonly InventoryDbContext _context;
public UnitOfWork(InventoryDbContext context)
{
_context = context;
GeneralRegionMasters = new GeneralRegionMasterRepository(_context);
GeneralSubRegionMasters = new GeneralSubRegionMasterRepository(_context);
GeneralCountryMasters = new GeneralCountryMasterRepository(_context);
GeneralStateMasters = new GeneralStateMasterRepository(_context);
GeneralCityMasters = new GeneralCityMasterRepository(_context);
}
public IGeneralRegionMasterRepository GeneralRegionMasters { get; private set; }
public IGeneralSubRegionMasterRepository GeneralSubRegionMasters { get; private set; }
public IGeneralCountryMasterRepository GeneralCountryMasters { get; private set; }
public IGeneralStateMasterRepository GeneralStateMasters { get; private set; }
public IGeneralCityMasterRepository GeneralCityMasters { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
}
我想知道它对应用程序的性能影响。预先感谢您的帮助。
我 运行 遇到了您过去描述的相同问题。代码的结构让人感觉非常沉重,因为您正在创建 70 个存储库的新实例,即使您可能只需要其中一个。这就是为什么我刚刚开始避免在直接使用 EF 时添加自己的 UoW 和 Repositories,因为 EF 已经内置了 Repositories 和 UoW(DbSets = Repos,Save Changes 会在所有 DbSet 更改结束时保存 UoW)。如果您不想直接针对 DbContext 进行编码,只需让您的 DbContext 直接实现 IUnitOfWork 接口,然后就可以了。还要在该 UnitOfWork 上公开所有 DbSet。然后你可以让它也实现 IMyDbContext 并让它公开 DbSets 并让这个接口也实现 IUnitOfWork(或者有 DbContext - > IMyDbContext - > IUnitOfWork)或者如果你不希望回购代码可以访问保存在底部。这最终使长 运行 变得更容易。无需维护奇怪的代码,无需创建 类。如果您切换到不使用 EF,您仍然可以在幕后使用那些相同的接口,唯一需要更改的是 DbSet 实现(也许您甚至可以将其设为通用 - 在 DbSet 上创建实现另一个的接口界面也一样)。就个人而言,我正在走 CQS 道路,所以我不必再担心回购或 UoW。 :)
编辑 尽我所能! :)
public interface IUnitOfWork
{
int Complete();
Task<int> CompleteAsync();
}
public interface IInventoryDbContext : IUnitOfWork
{
DbSet<GeneralRegionMaster> GeneralRegionMasters { get; }
DbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; }
... etc
}
public class MyDbContext : DbContext, IInventoryDbContext
{
public DbSet<GeneralRegionMaster> GeneralRegionMasters { get; set; }
public DbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; set;
}
public int Complete() => this.SaveChanges();
public Task<int> CompleteAsync() => this.SaveChangesAsync();
}
如果你只做了控制器关卡:
public class MyController : Controller
{
private readonly IInventoryDbContext _context;
public MyController(IInventoryDbContext context)
{
_context = context;
}
public JsonResult CreateGeneralRegionMaster(GeneralRegionMaster entity)
{
_context.GeneralRegionMaster.Add(entity);
var result = _context.Complete();
return Json(result == 1);
}
}
同样,您可以对 DbSet 做一些不同的事情,而是这样做:
public interface IRepo<T> where T: class
{
// Expose whatever methods you want here
}
public class MyDbSet<T> : DbSet<T>, IRepo<T> where T: class
{
}
然后这个改变:
public interface IInventoryDbContext : IUnitOfWork
{
IRepo<GeneralRegionMaster> GeneralRegionMasters { get; }
IRepo<GeneralSubRegionMaster> GeneralSubRegionMasters { get; }
... etc
}
public class MyDbContext : DbContext, IInventoryDbContext
{
public MyDbSet<GeneralRegionMaster> GeneralRegionMasters { get; set; }
public MyDbSet<GeneralSubRegionMaster> GeneralSubRegionMasters { get; set; }
public IRepo<GeneralRegionMaster> GeneralRegionMastersRepo => GeneralRegionMasters;
public IRepo<GeneralSubRegionMaster> GeneralSubRegionMastersRepo => GeneralSubRegionMasters;
public int Complete() => this.SaveChanges();
public Task<int> CompleteAsync() => this.SaveChangesAsync();
}
回复:
When UnitOfWork initializes, it creates object for all table's entity which is present in UnitOfWork. So it can be heavy for application load.
您不需要在 UoW 构造函数中初始化所有的 repo 实例。 您可以在相应的getter中需要它们时创建它们(延迟初始化):
private IGeneralRegionMasterRepository _generalRegionMasters;
public IGeneralRegionMasterRepository GeneralRegionMasters {
get {
if (_generalRegionMasters == null) {
_generalRegionMasters = new GeneralRegionMasterRepository(_context);
}
return _generalRegionMasters;
}
}