EF Core 倉儲模式

流年sugar發表於2024-11-06

資料庫:SqlServer為例

安裝包:

資料庫連線

DbContext

public class TestDbContext:DbContext
{
    public TestDbContext(DbContextOptions<TestDbContext> options) : base(options)
    {
    }
    public DbSet<User> Users { get; set; }
}

註冊資料庫上下文

builder.Services.AddDbContext<TestDbContext>(options =>
 {
     options.UseSqlServer("ConnectionString");
 });
 //依賴注入倉儲
 builder.Services.AddTransient(typeof(IRepository<>),typeof(BaseRepository<>));

倉儲介面----IRepository

public interface IRepository<T>  where T : class
{
    /// <summary>
    /// 新增
    /// </summary>
    /// <param name="t">要新增的資訊</param>
    void Insert(T t);
    /// <summary>
    /// 新增
    /// </summary>
    /// <param name="t">要新增的資訊</param>
    Task InsertAsync(T t);
    /// <summary>
    /// 批次新增
    /// </summary>
    /// <param name="t">要新增的資訊</param>
    void InsertRange(List<T> t);
    /// <summary>
    /// 批次新增
    /// </summary>
    /// <param name="t">要新增的資訊</param>
    Task InsertRangeAsync(List<T> t);
    /// <summary>
    /// 更新單個物件
    /// </summary>
    /// <param name="t">要更改的資訊</param>
    void Update(T t);

    /// <summary>
    /// 單個更新物件-非同步
    /// </summary>
    /// <param name="t">要更改的資訊</param>
    Task UpdateAsync(T t);
    /// <summary>
    /// 批次更新
    /// </summary>
    /// <param name="t">要修改的資訊</param>
    void UpdateRange(List<T> t);
    /// <summary>
    /// 批次更新-非同步
    /// </summary>
    /// <param name="t">要修改的資訊</param>
    Task UpdateRangeAsync(List<T> t);
    /// <summary>
    /// 刪除
    /// </summary>
    /// <param name="t">要刪除的資訊</param>
    void Delete(T t);
    /// <summary>
    /// 刪除-非同步
    /// </summary>
    /// <param name="t">要刪除的資訊</param>
    Task DeleteAsync(T t);
    /// <summary>
    /// 批次刪除
    /// </summary>
    /// <param name="t">要刪除的資訊</param>
    void DeleteRange(List<T> t);
    /// <summary>
    /// 批次刪除-非同步
    /// </summary>
    /// <param name="t">要刪除的資訊</param>
    Task DeleteRangeAsync(List<T> t);
    /// <summary>
    /// 單個查詢
    /// </summary>
    /// <param name="id">要獲取物件的編號</param>
    /// <returns>物件</returns>
    T Get(int id);

    /// <summary>
    /// 單個查詢=非同步
    /// </summary>
    /// <param name="id">要獲取物件的編號</param>
    /// <returns></returns>
    Task<T> GetAsync(int id);
    /// <summary>
    /// 獲取物件列表
    /// </summary>
    /// <returns>物件集合</returns>
   IQueryable<T> GetAll();
   
    /// <summary>
    /// 分頁查詢
    /// </summary>
    /// <param name="pageindex">頁碼</param>
    /// <param name="pagesize">每頁獲取數量</param>
    /// <param name="where">條件查詢</param>
    /// <param name="orderBy">條件排序</param>
    /// <param name="orderAsc">true 升序</param>
    /// <param name="totalcount">總條數</param>
    /// <returns>物件集合</returns>
    IQueryable<T> GetPage(int pageindex, int pagesize, Func<T, bool> where, Func<T, DateTime> orderBy, bool orderAsc, out int totalcount);
}

倉儲實現---BaseRepository

public class BaseRepository<T> : IRepository<T> where T : class, new()
{
    private readonly TestDbContext _context;

    public BaseRepository(TestDbContext context)
    {
        _context = context;
    }
    #region 刪除
    /// <summary>
    /// 單個刪除
    /// </summary>
    /// <param name="t">帶主鍵的實體</param>
    public void Delete(T t)
    {
        _context.Remove(t);
    }

    /// <summary>
    /// 單個刪除-非同步
    /// </summary>
    /// <param name="t">帶主鍵的實體</param>
    /// <returns></returns>
    public async Task DeleteAsync(T t)
    {
        await Task.Run(() => _context.Remove(t));
    }

    /// <summary>
    /// 批次刪除
    /// </summary>
    /// <param name="t">帶主鍵的實體集合</param>
    public void DeleteRange(List<T> t)
    {
        _context.RemoveRange(t);
    }

    /// <summary>
    /// 批次刪除-非同步
    /// </summary>
    /// <param name="t">帶主鍵的實體集合</param>
    /// <returns></returns>
    public async Task DeleteRangeAsync(List<T> t)
    {
        await Task.Run(() => _context.Set<T>().RemoveRange(t));
    }
    #endregion

    #region 查詢

    /// <summary>
    /// 單個查詢
    /// </summary>
    /// <param name="id">主鍵</param>
    /// <returns></returns>
    public T Get(int id)
    {
        return _context.Find<T>(id) ?? new T();
    }
    /// <summary>
    /// 集合查詢
    /// </summary>
    /// <returns></returns>
    public IQueryable<T> GetAll()
    {
        return _context.Set<T>().AsNoTracking();
    }
    /// <summary>
    /// 單個查詢-非同步
    /// </summary>
    /// <param name="id">主鍵</param>
    /// <returns></returns>
    public async Task<T> GetAsync(int id)
    {
        return await _context.FindAsync<T>(id) ?? new T();
    }
    /// <summary>
    /// 分頁查詢
    /// </summary>
    /// <param name="pageindex">頁碼</param>
    /// <param name="pagesize">每頁獲取數量</param>
    /// <param name="where"></param>
    /// <param name="orderBy"></param>
    /// <param name="orderAsc"></param>
    /// <param name="totalcount">結果總條數</param>
    /// <returns></returns>
    public IQueryable<T> GetPage(int pageindex, int pagesize, Func<T, bool> where, Func<T, DateTime> orderBy, bool orderAsc, out int totalcount)
    {
        var query = GetAll().Where(where);
        if (orderAsc)
        {
            query = query.OrderBy(orderBy);
            //query = query.OrderBy(orderBy).AsQueryable();
        }
        else
        {
            query = query.OrderBy(orderBy);
            //query = query.OrderByDescending(orderBy).AsQueryable() ;
        }
        totalcount = query.Count();
        return query.Skip((pageindex - 1) * pagesize).Take(pagesize).AsQueryable();
    }
    #endregion

    #region 新增
    /// <summary>
    /// 新增
    /// </summary>
    /// <param name="t"></param>
    public void Insert(T t)
    {
        _context.Add(t);
    }

    /// <summary>
    /// 單個新增
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public async Task InsertAsync(T t)
    {
        await _context.AddAsync(t);
    }

    /// <summary>
    /// 批次新增
    /// </summary>
    /// <param name="t"></param>
    public void InsertRange(List<T> t)
    {
        _context.AddRange(t);
    }

    /// <summary>
    /// 批次新增-非同步
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public async Task InsertRangeAsync(List<T> t)
    {
        await _context.AddRangeAsync(t);
    }

    #endregion

    #region 更新
    /// <summary>
    /// 更新單個物件
    /// </summary>
    /// <param name="t">更新物件</param>
    public void Update(T t)
    {
        _context.Update(t);
    }

    /// <summary>
    /// 更新單個物件-非同步
    /// </summary>
    /// <param name="t">更新物件</param>
    /// <returns></returns>
    public async Task UpdateAsync(T t)
    {
        await Task.Run(() => { _context.Update(t); });
    }

    /// <summary>
    /// 批次更新
    /// </summary>
    /// <param name="t"></param>
    public void UpdateRange(List<T> t)
    {
        _context.UpdateRange(t);
    }

    /// <summary>
    /// 批次更新-非同步
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public async Task UpdateRangeAsync(List<T> t)
    {
        await Task.Run(() => { _context.UpdateRange(); });
    }
    #endregion

    public bool SaveChange()
    {
        return _context.SaveChanges() > 0;
    }
    public async Task<bool> SaveChangeAsync()
    {
        return await _context.SaveChangesAsync() > 0;
    }
}

倉儲使用

public class UserService: IUserService
{
    private readonly IRepository<User> _userRepository;

    public UserService(IRepository<User> userRepository)
    {
        _userRepository = userRepository;
    }

    public async Task GetUsers(string name)
    {
        var result= await _userRepository.GetAll().Where(u => u.Name == name).ToListAsync();
    }
}

相關文章