正大为怀 發表於 2026-4-27 09:13:00

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

<div>
<div dir="ltr">
<div>
<h1>1. 安装 NuGet</h1>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<pre><code>SqlSugarCore</code></pre>
</div>
</div>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>2. SqlSugar 数据库上下文</h1>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>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
      });
    }
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>3. 实体</h1>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>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; }
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>4. 仓储</h1>
<div>&nbsp;</div>
<h2>接口</h2>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>public interface IRepository&lt;T&gt; where T : class, new()
{
    // 查询
    Task&lt;T&gt; GetByIdAsync(int id);
    Task&lt;List&lt;T&gt;&gt; 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);
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<h2>实现</h2>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>using SqlSugar;

namespace Demo;

public class Repository&lt;T&gt; : IRepository&lt;T&gt; where T : class, new()
{
    private readonly ISqlSugarClient _db;

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

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

    public async Task&lt;List&lt;T&gt;&gt; GetListAsync()
      =&gt; await _db.Queryable&lt;T&gt;().ToListAsync();

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

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

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

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

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

    public async Task DeleteImmediateAsync(T entity)
      =&gt; await _db.Deleteable(entity).ExecuteCommandAsync();
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>5. 工作单元 UnitOfWork</h1>
<div>&nbsp;</div>
<div>管理所有仓储 + 统一提交队列事务</div>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>namespace Demo;

public interface IUnitOfWork
{
    IRepository&lt;Product&gt; Products { get; }
    IRepository&lt;Order&gt;    Orders { get; }

    Task SaveChangesAsync();
}

public class UnitOfWork : IUnitOfWork
{
    private readonly ISqlSugarClient _db;

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

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

    private IRepository&lt;Order&gt;? _orderRepo;
    public IRepository&lt;Order&gt; Orders
      =&gt; _orderRepo ??= new Repository&lt;Order&gt;(_db);

    // ======================
    // 提交所有 AddQueue 操作
    // 自动开启一个事务
    // 全部成功/全部回滚
    // ======================
    public async Task SaveChangesAsync()
    {
      await _db.SaveQueuesAsync();
    }
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>6. 服务层</h1>
<div>&nbsp;</div>
<h2>规则</h2>
<div>&nbsp;</div>
<div>1)单表 / 多表增删改
<div>&nbsp;</div>
→ 走 Repository + UnitOfWork
<div>&nbsp;</div>
→ 用 AddQueue
<div>&nbsp;</div>
→ SaveChangesAsync 统一事务,原子性</div>
<div>&nbsp;</div>
<div>2)多表联查 / 复杂查询 / 分页
<div>&nbsp;</div>
→ 直接用 ISqlSugarClient
<div>&nbsp;</div>
→ 不进仓储,不进 Uow</div>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>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&lt;List&lt;OrderDto&gt;&gt; GetOrderList()
    {
      return await _db.Queryable&lt;Order&gt;()
                        .LeftJoin&lt;Product&gt;((o, p) =&gt; o.ProductId == p.Id)
                        .Select((o, p) =&gt; new OrderDto
                        {
                            OrderId   = o.Id,
                            ProductName = p.Name,
                            Stock       = p.Stock,
                            Price       = o.Price
                        })
                        .ToListAsync();
    }

    public async Task&lt;List&lt;OrderDto&gt;&gt; GetPageList(int pageIndex, int pageSize)
    {
      return await _db.Queryable&lt;Order&gt;()
                        .LeftJoin&lt;Product&gt;((o, p) =&gt; o.ProductId == p.Id)
                        .Select((o, p) =&gt; new OrderDto
                        {
                            OrderId   = o.Id,
                            ProductName = p.Name
                        })
                        .ToPageListAsync(pageIndex, pageSize);
    }
}
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<div>&nbsp;</div>
<hr>
<div>&nbsp;</div>
<h1>7. Program.cs 注册</h1>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton&lt;SqlSugarContext&gt;();
builder.Services.AddScoped&lt;IUnitOfWork, UnitOfWork&gt;();
builder.Services.AddScoped&lt;OrderService&gt;();

var app = builder.Build();
app.Run();
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>8. 知识点总结</h1>
<div>&nbsp;</div>
<h2>① <code>AddQueue()</code> 是什么?</h2>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>_db.Insertable(entity).AddQueueAsync()
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<ul>
<li>不执行 SQL</li>
<li>把操作加入事务队列</li>
<li>必须调用 <code>SaveQueuesAsync()</code> 才会真正执行</li>
<li>多个操作共用一个事务,保证原子性</li>
</ul>
<div>&nbsp;</div>
<h2>② <code>ExecuteCommandAsync()</code> 是什么?</h2>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>_db.Insertable(entity).ExecuteCommandAsync()
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<ul>
<li>立即执行 SQL</li>
<li>不入队</li>
<li>不需要 <code>SaveChanges</code></li>
<li>无事务,执行完就落库</li>
</ul>
<div>&nbsp;</div>
<h2>③ 三层用法规则</h2>
<div>&nbsp;</div>
<h3>1)单表 / 多表增删改</h3>
<div>&nbsp;</div>
<div>→ 走 <code>Repository + UnitOfWork</code>
<div>&nbsp;</div>
→ 使用 <code>Add/Update/Delete</code>(AddQueue)
<div>&nbsp;</div>
→ 最后 <code>SaveChangesAsync</code>
<div>&nbsp;</div>
→ 一个事务,原子性,要么全成功要么全失败</div>
<div>&nbsp;</div>
<h3>2)多表联查 / 复杂查询 / 报表 / 分页</h3>
<div>&nbsp;</div>
<div>→ 直接使用 <code>ISqlSugarClient</code>
<div>&nbsp;</div>
→ 不进仓储,不进 UnitOfWork
<div>&nbsp;</div>
→ 自由 <code>Join / Where / OrderBy / Select / ToPageList</code></div>
<div>&nbsp;</div>
<h3>3)Service 结构</h3>
<div>&nbsp;</div>
<div>
<div dir="ltr">
<div>
<pre><code>Service
├─ 写操作(增删改)
│   → _uow.仓储.Add/Update/Delete
│   → _uow.SaveChangesAsync()
└─ 读操作(查询/联表/分页)
    → _db.Queryable&lt;T&gt;().Join&lt;T2&gt;().Select(...)
</code></pre>
</div>
<div>&nbsp;</div>
</div>
</div>
<hr>
<div>&nbsp;</div>
<h1>9. 总结</h1>
<div>&nbsp;</div>
<ul>
<li>AddQueue:先排队,最后统一事务执行</li>
<li>ExecuteCommand:立即执行,不排队,无事务</li>
<li>增删改走 Uow,查询直接用 SqlSugar</li>
<li>仓储只管单表,Uow 管事务,Service 管业务</li>
</ul><br><br>
来源:https://www.cnblogs.com/chuansheng/p/19915717
頁: [1]
查看完整版本: .NET SqlSugar 仓储、工作单元、服务层