ASP.NET Core仓储模式
一、仓储模式
仓储(Repository)模式是一种设计模式,用于在应用程序的数据访问层和业务逻辑层之间创建抽象层,它的主要目的是实现松耦合,并保持领域对象的持久性无知,通过仓储模式,我们可以将数据访问的逻辑写在单独的类中,即仓储,负责和业务层进行持久化通信。
二、仓储模式的优点
1、解耦:业务层无需知道具体实现,达到分离关注点。
2、提高维护性:对数据库访问的维护提高,对于仓储的改变并不改变业务的逻辑。
3、更好的可重用性:泛型仓储可以在多个实体类型之间共享和重用,减少了重复的代码编写和维护工作。
4、类型安全性:使用泛型仓储可以在编译时就约束数据的类型,减少了运行时类型错误的可能性。
5、简洁性:通过使用通用的方法和接口来简化数据访问的逻辑,提供统一的CRUD(增删改查)操作接口。
6、更好的可测试性:数据访问逻辑可以更容易地进行单元测试,因为可以使用模拟或者假数据来代替实际的数据存储。
7、更好的扩展性:可以通过继承或者接口实现来扩展其功能,例如添加自定义的查询方法或者过滤器。
三、仓储模式的实现
定义实体接口和父类
我们需要定义一个实体接口和一个实体父类,实体接口定义了实体的基本属性和方法,而实体父类则提供了这些属性和方法的默认实现。
public interface IEntityBase<TId> { TId F_Id { get; } } public abstract class EntityBase : EntityBase<long>//默认字段类型是long { } public abstract class EntityBase<TId> : IEntityBase<TId> { public virtual TId F_Id { get; set; } }
定义Repository接口
我们定义一个Repository接口,指定新增、删除等方法。
public interface IRepository<T, TId> where T : IEntityBase<TId> { IDbContextTransaction BeginTransaction(); IQueryable<T> Query(); void Add(T entity); void AddRange(IEnumerable<T> entity); void Delete(T entity); void Save(); Task SaveAsync(); }
实现Repository类
我们实现Repository类,这个类实现了Repository接口,并提供了具体的数据库操作逻辑。
public class Repository<T, TId> : IRepository<T, TId> where T : class, IEntityBase<TId> { private DemoDbContext Context { get; } private DbSet<T> DbSet { get; } public Repository(DemoDbContext context) { Context = context; DbSet = Context.Set<T>(); } public IDbContextTransaction BeginTransaction() { return Context.Database.BeginTransaction(); } public IQueryable<T> Query() { return DbSet; } public void Add(T entity) { DbSet.Add(entity); } public void AddRange(IEnumerable<T> entity) { DbSet.AddRange(entity); } public void Delete(T entity) { DbSet.Remove(entity); } public void Save() { Context.SaveChanges(); } public async Task SaveAsync() { await Context.SaveChangesAsync(); } }
四、泛型仓储的使用
在ASP.NET Core项目中,我们可以使用泛型仓储来封装EntityFrameworkCore的CRUD操作,以下是一个简单的示例:
public class UnitOfWork : IUnitOfWork, IDisposable { private readonly IServiceProvider _provider; private Hashtable repositorys; private IDbContextTransaction _dbTransaction; private DemoDbContext _context; public UnitOfWork(IServiceProvider provider) { _provider = provider; _context = new DemoDbContext(); } public IRepository<TEntity, TKey> Repository<TEntity, TKey>() where TEntity : class, IEntity<TKey> { var repo = repositorys[typeof(TEntity).FullName] as Lazy<IRepository<TEntity, TKey>>; if (repo == null) { repo = new Lazy<IRepository<TEntity, TKey>>(() => { var context = _context ?? (_context = ActivatorUtilities.CreateInstance<DemoDbContext>(_provider.GetService)); return new Repository<TEntity, TKey>(context); }, LazyThreadSafetyMode.ExecutionAndPublication); repositorys.Add(typeof(TEntity).FullName, repo); } return repo.Value; } public void BeginTransaction() { if (_dbTransaction != null) throw new InvalidOperationException("There is already an open transaction"); _dbTransaction = _context.Database.BeginTransaction(); } public int Commit() => _dbTransaction?.Commit().GetAwaiter().GetResult(); public async Task<int> CommitAsync() => await _dbTransaction?.CommitAsync(); public void Dispose() => _dbTransaction?.Dispose(); }
在这个示例中,我们使用了Lazy<T>
来延迟初始化仓储对象,并在需要时创建它们,这样可以确保在整个应用程序生命周期中只创建一个仓储实例,从而提高性能。
到此,以上就是小编对于“asp.net core 仓储”的问题就介绍到这了,希望介绍的几点解答对大家有用,有任何问题和不懂的,欢迎各位朋友在评论区讨论,给我留言。