将基本存储库作为抽象类的通用存储库实现



net核心项目。我正在尝试实现通用存储库模式。我有一个抽象的基础知识库。所以我正在覆盖基本存储库并创建我的其他存储库。实施情况如下。

BaseRepository.cs

public abstract class BaseRepository<T>: IBaseRepository<T>
where T : class
{
private readonly DbContext dbContext;
private readonly DbSet<T> dbSet;
public BaseRepository(DbContext dbContext)
{
this.dbContext = dbContext;
this.dbSet = dbContext?.Set<T>();
}
public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includes)
{
IQueryable<T> query = this.dbSet;
foreach (Expression<Func<T, object>> include in includes)
{
query = query.Include(include);
}
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
query = orderBy(query);
}
return await query.ToListAsync().ConfigureAwait(false);
}
}
}

存储库.cs

public class Repository<T> : BaseRepository<T>, IRepository<T>
where T : class
{
private readonly DbContext dbContext;
private readonly DbSet<T> dbSet;
public Repository(DbContext context) : base(context)
{
}
public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includes)
{
IQueryable<T> query = this.dbSet;
foreach (Expression<Func<T, object>> include in includes)
{
query = query.Include(include);
}
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
query = orderBy(query);
}
return await query.ToListAsync().ConfigureAwait(false);
}
}
}

UnitOfWork.cs

public class UnitOfWork<TContext> : IUnitOfWork<TContext>
where TContext : DbContext, IDisposable
{
private readonly MyContext context;
private Dictionary<(Type type, string name), object> _repositories;
public UnitOfWork(MyContext myContext)
{
if (this.context == null)
{
this.context = myContext;
}
}
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
{
return (IRepository<TEntity>)GetOrAddRepository(typeof(TEntity), new Repository<TEntity>(Context));
}
public async Task<int> CompleteAsync()
{
try
{
return await this.context.SaveChangesAsync().ConfigureAwait(false);
}
catch (DbUpdateConcurrencyException ex)
{
ex.Entries.Single().Reload();
return await this.context.SaveChangesAsync().ConfigureAwait(false);
}
}
internal object GetOrAddRepository(Type type, object repo)
{
_repositories ??= new Dictionary<(Type type, string Name), object>();
if (_repositories.TryGetValue((type, repo.GetType().FullName), out var repository)) return repository;
_repositories.Add((type, repo.GetType().FullName), repo);
return repo;
}
}
}

然后在我注册时的startup.cs文件中

services.AddDbContext<MyContext>(options =>
options.UseSqlServer(this.Configuration["AzureSQLConnectionString"]));
services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
services.AddScoped<IUnitOfWork, UnitOfWork>();

UnitofWork在使用泛型类型时出错。"UnitofWork"需要1种类型的参数。然后我添加了services.AddScoped<IUnitOfWork, UnitOfWork<MyContext>>()。现在它在Repository.cs中的GetAsync方法中抛出错误。错误为Parameter:source是必需的,不能为空。然后我找到

IQueryable查询=this.dbSet;

查询为空。所以我所理解的是,我在建立与数据库的连接时遇到了一些问题。有人能帮我吗?我到底做错了什么?如有任何帮助,我们将不胜感激。谢谢

按如下方式更改这些类:

public abstract class BaseRepository<T>: IBaseRepository<T>
where T : class
{
protected readonly DbContext dbContext;
protected readonly DbSet<T> dbSet;
public BaseRepository(DbContext dbContext)
{
this.dbContext = dbContext;
this.dbSet = dbContext?.Set<T>();
}
public virtual async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, params Expression<Func<T, object>>[] includes)
{
IQueryable<T> query = this.dbSet;
foreach (Expression<Func<T, object>> include in includes)
{
query = query.Include(include);
}
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
query = orderBy(query);
}
return await query.ToListAsync().ConfigureAwait(false);
}
}
public class Repository<T> : BaseRepository<T>, IRepository<T>
where T : class
{

public Repository(DbContext context) : base(context)
{
}
//override GetAsync if different than base. In your case it is not.
}

最新更新