.NET SqlSugar 仓储、工作单元、服务层

1. 安装 NuGet

 

SqlSugarCore

 


 

2. SqlSugar 数据库上下文

 

using SqlSugar;

namespace Demo;

public class SqlSugarContext
{
    public ISqlSugarClient Db { get; }

    public SqlSugarContext()
    {
        Db = new SqlSugarClient(new ConnectionConfig
        {
            ConnectionString = "Data Source=.;Database=DemoDb;UID=sa;PWD=123;",
            DbType = DbType.SqlServer,
            IsAutoCloseConnection = true
        });
    }
}

 


 

3. 实体

 

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Stock { get; set; }
}

public class Order
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public decimal Price { get; set; }
}

public class OrderDto
{
    public int OrderId { get; set; }
    public string ProductName { get; set; }
    public int Stock { get; set; }
    public decimal Price { get; set; }
}

 


 

4. 仓储

 

接口

 

public interface IRepository<T> where T : class, new()
{
    // 查询
    Task<T> GetByIdAsync(int id);
    Task<List<T>> GetListAsync();

    // ==========================================
    // 1. 事务模式:AddQueue → 入队,不执行SQL
    // ==========================================
    void Insert(T entity);
    void Update(T entity);
    void Delete(T entity);

    // ==========================================
    // 2. 立即模式:ExecuteCommand → 直接执行SQL
    // ==========================================
    Task InsertImmediateAsync(T entity);
    Task UpdateImmediateAsync(T entity);
    Task DeleteImmediateAsync(T entity);
}

 

实现

 

using SqlSugar;

namespace Demo;

public class Repository<T> : IRepository<T> where T : class, new()
{
    private readonly ISqlSugarClient _db;

    public Repository(ISqlSugarClient db)
    {
        _db = db;
    }

    // ======================
    // 查询(直接执行)
    // ======================
    public async Task<T> GetByIdAsync(int id)
        => await _db.Queryable<T>().InSingleAsync(id);

    public async Task<List<T>> GetListAsync()
        => await _db.Queryable<T>().ToListAsync();

    // ======================
    // 事务模式:AddQueue
    // 只入队,不执行SQL
    // 必须等 SaveQueuesAsync 才执行
    // ======================
    public void Insert(T entity)
        => _db.Insertable(entity).AddQueue();

    public void Update(T entity)
        => _db.Updateable(entity).AddQueue();

    public void Delete(T entity)
        => _db.Deleteable(entity).AddQueue();

    // ======================
    // 立即模式:ExecuteCommand
    // 直接执行SQL,不走队列
    // 不需要 SaveChanges,无事务
    // ======================
    public async Task InsertImmediateAsync(T entity)
        => await _db.Insertable(entity).ExecuteCommandAsync();

    public async Task UpdateImmediateAsync(T entity)
        => await _db.Updateable(entity).ExecuteCommandAsync();

    public async Task DeleteImmediateAsync(T entity)
        => await _db.Deleteable(entity).ExecuteCommandAsync();
}

 


 

5. 工作单元 UnitOfWork

  管理所有仓储 + 统一提交队列事务  

namespace Demo;

public interface IUnitOfWork
{
    IRepository<Product> Products { get; }
    IRepository<Order>    Orders { get; }

    Task SaveChangesAsync();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly ISqlSugarClient _db;

    public UnitOfWork(SqlSugarContext context)
    {
        _db = context.Db;
    }

    // 懒加载仓储
    private IRepository<Product>? _productRepo;
    public IRepository<Product> Products
        => _productRepo ??= new Repository<Product>(_db);

    private IRepository<Order>? _orderRepo;
    public IRepository<Order> Orders
        => _orderRepo ??= new Repository<Order>(_db);

    // ======================
    // 提交所有 AddQueue 操作
    // 自动开启一个事务
    // 全部成功/全部回滚
    // ======================
    public async Task SaveChangesAsync()
    {
        await _db.SaveQueuesAsync();
    }
}

 


 

6. 服务层

 

规则

  1)单表 / 多表增删改   → 走 Repository + UnitOfWork   → 用 AddQueue   → SaveChangesAsync 统一事务,原子性   2)多表联查 / 复杂查询 / 分页   → 直接用 ISqlSugarClient   → 不进仓储,不进 Uow  

using SqlSugar;

namespace Demo;

public class OrderService
{
    private readonly IUnitOfWork      _uow;  // 增删改 + 事务
    private readonly ISqlSugarClient  _db;   // 查询/联表

    public OrderService(IUnitOfWork uow, SqlSugarContext context)
    {
        _uow = uow;
        _db  = context.Db;
    }

    // ==================================================
    // 1)增删改(单表/多表)→ 走 Uow + 事务 + 原子性
    // ==================================================
    public async Task CreateOrder(Order order)
    {
        // 1. 订单入队
        _uow.Orders.Insert(order);

        // 2. 扣库存入队
        var product = await _uow.Products.GetByIdAsync(order.ProductId);
        product.Stock--;
        _uow.Products.Update(product);

        // 3. 统一提交:开启一个事务,执行所有队列
        await _uow.SaveChangesAsync();
    }

    // ==================================================
    // 单表立即执行:不使用事务,直接插入
    // ==================================================
    public async Task AddProductImmediate(Product product)
    {
        // 直接执行SQL,无事务,不需要 SaveChanges
        await _uow.Products.InsertImmediateAsync(product);
    }

    // ==================================================
    // 2)多表联查 / 复杂查询 / 分页
    // 直接用 _db,不走仓储,不走 Uow
    // ==================================================
    public async Task<List<OrderDto>> GetOrderList()
    {
        return await _db.Queryable<Order>()
                        .LeftJoin<Product>((o, p) => o.ProductId == p.Id)
                        .Select((o, p) => new OrderDto
                        {
                            OrderId     = o.Id,
                            ProductName = p.Name,
                            Stock       = p.Stock,
                            Price       = o.Price
                        })
                        .ToListAsync();
    }

    public async Task<List<OrderDto>> GetPageList(int pageIndex, int pageSize)
    {
        return await _db.Queryable<Order>()
                        .LeftJoin<Product>((o, p) => o.ProductId == p.Id)
                        .Select((o, p) => new OrderDto
                        {
                            OrderId     = o.Id,
                            ProductName = p.Name
                        })
                        .ToPageListAsync(pageIndex, pageSize);
    }
}

   


 

7. Program.cs 注册

 

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<SqlSugarContext>();
builder.Services.AddScoped<IUnitOfWork, UnitOfWork>();
builder.Services.AddScoped<OrderService>();

var app = builder.Build();
app.Run();

 


 

8. 知识点总结

 

AddQueue() 是什么?

 

_db.Insertable(entity).AddQueueAsync()

 

  • 不执行 SQL
  • 把操作加入事务队列
  • 必须调用 SaveQueuesAsync() 才会真正执行
  • 多个操作共用一个事务,保证原子性

 

ExecuteCommandAsync() 是什么?

 

_db.Insertable(entity).ExecuteCommandAsync()

 

  • 立即执行 SQL
  • 不入队
  • 不需要 SaveChanges
  • 无事务,执行完就落库

 

③ 三层用法规则

 

1)单表 / 多表增删改

  → 走
Repository + UnitOfWork   → 使用
Add/Update/Delete(AddQueue)   → 最后
SaveChangesAsync   → 一个事务,原子性,要么全成功要么全失败  

2)多表联查 / 复杂查询 / 报表 / 分页

  → 直接使用
ISqlSugarClient   → 不进仓储,不进 UnitOfWork   → 自由
Join / Where / OrderBy / Select / ToPageList  

3)Service 结构

 

Service
├─ 写操作(增删改)
│   → _uow.仓储.Add/Update/Delete
│   → _uow.SaveChangesAsync()
└─ 读操作(查询/联表/分页)
    → _db.Queryable<T>().Join<T2>().Select(...)

 


 

9. 总结

 

  • AddQueue:先排队,最后统一事务执行
  • ExecuteCommand:立即执行,不排队,无事务
  • 增删改走 Uow,查询直接用 SqlSugar
  • 仓储只管单表,Uow 管事务,Service 管业务

文章摘自:https://www.cnblogs.com/chuansheng/p/19915717