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
相关产品推荐
相关产品推荐

