Repository模式是否必须搭配Unit of Work?相关实现与架构疑问咨询
Let’s unpack each of your questions clearly—these two patterns are often paired together, but they’re not mandatory partners:
1. Does "Repository Pattern" default to Repository + Unit of Work? Are there scenarios for Repository alone?
No, the Repository pattern is not inherently tied to Unit of Work (UoW). The Repository pattern’s core job is to abstract data access behind a collection-like interface, isolating your domain layer from direct database or ORM calls. UoW, by contrast, focuses on coordinating transactions and ensuring consistency across multiple data operations (often across multiple Repositories).
There are plenty of valid scenarios for using Repository alone:
- Simple CRUD apps where you only interact with one entity type (e.g., a small tool managing employee profiles, with no cross-entity transactions needed).
- When your ORM already handles transactional consistency for single-Repo operations (like EF Core’s
DbContexttracking changes for a single entity set). - In microservices where each service owns a single bounded context, and most operations don’t require cross-Repo coordination.
The confusion often comes from older tutorials that paired them out of habit (or because early ORMs required explicit UoW handling), but they’re distinct, independent patterns.
2. If using UoW, should I only access Repositories through it?
Yes, this is strongly recommended to preserve the purpose of UoW. Here’s why:
- UoW exists to manage a single transactional boundary. If consumers can instantiate and use Repositories directly, they might bypass the UoW’s transaction control—leading to partial commits or inconsistent data (e.g., saving changes to one Repo without rolling back if another operation fails).
- It simplifies dependency management: Consumers only need to depend on the UoW interface, not individual Repository interfaces, reducing coupling in your codebase.
To enforce this, you can:
- Register only the UoW with your dependency injection container (instead of registering individual Repositories).
- Make Repository constructors internal (so only the UoW can instantiate them).
- Design your UoW to expose Repositories as read-only properties, preventing consumers from creating new instances on their own.
3. Is adding an Update method to Repository a bad practice?
This depends entirely on your data access implementation:
- In ORM-based systems (like EF Core, NHibernate): Yes, an explicit
Updatemethod is usually unnecessary and a sign of misunderstanding the pattern. ORMs track changes to entities you retrieve from the Repository—when you call UoW’sComplete()(orSaveChanges()), the ORM automatically persists those changes. Adding anUpdatemethod here duplicates work and breaks the "collection-like" abstraction (aList<T>doesn’t have anUpdatemethod—you just modify the item in the list). - In non-ORM systems (like raw ADO.NET, Dapper without change tracking): No, an
Updatemethod is often the most practical approach. Since there’s no automatic change tracking, you need a way to tell the data layer which entity has been modified and needs to be persisted.
The discrepancy in tutorials comes from some authors either working with older ORMs that lacked robust change tracking, or leaning into a more procedural style instead of embracing the Repository’s collection-focused abstraction.
Core Takeaway
The Repository pattern does not require Unit of Work. They’re complementary tools: use UoW when you need to coordinate transactions across multiple data operations, and use Repository alone when you just need to abstract data access for a single entity set without transactional coordination.
内容的提问来源于stack exchange,提问作者Álvaro García

