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;
  }
}