You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForms中使用Repository模式与工作单元的方式是否正确?

你的用法是正确的,但有优化空间

为什么当前写法没问题

你每次用using创建UnitOfWork的做法是符合设计原则的:

  • UnitOfWork的核心作用是封装单次业务操作的数据库连接和事务管理,短生命周期的实例能确保数据库连接及时释放,避免连接池耗尽的问题
  • using语句会自动调用IDisposable接口的Dispose方法,帮你清理UnitOfWork内部的资源(比如打开的数据库连接),不会出现资源泄漏

可以优化的点和正确使用方式

1. 频繁筛选场景:优先客户端缓存,减少数据库访问

你现在每次文本框变化都查全表再过滤,数据量小的时候没问题,但数据量大时会重复消耗数据库资源。可以把全表数据缓存到窗体的私有字段里,筛选时直接操作内存数据:

private List<Product> _allProducts;

public Form1()
{
    InitializeComponent();
    LoadAllProducts();
}

void LoadAllProducts()
{
    using (var uow = new UnitOfWork(AppConnection.ConnectionString))
    {
        _allProducts = uow.ProductRepository.GetAll().ToList();
        dataGridView1.DataSource = _allProducts;
    }
}

private void textBox1_TextChanged(object sender, EventArgs e)
{
    var keyword = textBox1.Text.Trim();
    var filteredList = string.IsNullOrEmpty(keyword) 
        ? _allProducts 
        : _allProducts.Where(c => c.Ident.Contains(keyword)).ToList();
    dataGridView1.DataSource = filteredList;
}

2. 大数据量场景:在Repository层做数据库层面筛选

如果数据量太大不适合缓存全表,应该给ProductRepository添加带筛选条件的方法,直接在SQL里过滤(用Dapper写带参数的查询),减少网络传输的数据量:

// 在ProductRepository里添加方法
public IEnumerable<Product> GetByIdentContains(string keyword)
{
    var sql = "SELECT * FROM Products WHERE Ident LIKE @Keyword";
    return _connection.Query<Product>(sql, new { Keyword = $"%{keyword}%" });
}

// 窗体里调用
private void textBox1_TextChanged(object sender, EventArgs e)
{
    var keyword = textBox1.Text.Trim();
    using (var uow = new UnitOfWork(AppConnection.ConnectionString))
    {
        var filteredList = string.IsNullOrEmpty(keyword)
            ? uow.ProductRepository.GetAll().ToList()
            : uow.ProductRepository.GetByIdentContains(keyword).ToList();
        dataGridView1.DataSource = filteredList;
    }
}

3. 事务场景:复用同一个UnitOfWork实例

如果需要执行多个关联操作(比如同时新增产品和更新库存),必须复用同一个UnitOfWork实例,确保这些操作在同一个事务里完成:

private void SaveProductAndUpdateStock(Product product, int stockChange)
{
    using (var uow = new UnitOfWork(AppConnection.ConnectionString))
    {
        try
        {
            uow.ProductRepository.Add(product);
            uow.StockRepository.UpdateStock(product.Id, stockChange);
            uow.Commit(); // 提交事务
        }
        catch
        {
            uow.Rollback(); // 出错回滚
            throw;
        }
    }
}

内容的提问来源于stack exchange,提问作者Jocelyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 14:45:55