UOW and Repository Pattern in EF5

核能气质少年 提交于 2019-12-06 05:37:00

问题


This is about some confusion I have about some of the entity framework material I have found from here: https://www.asp.net/

On this Page it explains how to wrap a dbcontext using a repository and to wrap a repository using a a unit of work class: http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

However, on this page it states that a dbcontext is already a combination of both the UOW pattern and the repository pattern: https://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext(v=vs.103).aspx

So if the problem that these patterns solve are already solved by dbcontext, why re-implement these patterns with EF5?

Also, in the tutorial, the UnitOfWork class doesn't seem to show any benefit that UOW is supposed to give. for instance it states: "That way, when a unit of work is complete you can call the SaveChanges method on that instance of the context and be assured that all related changes will be coordinated. "

but all it seems to do is wrap the dbcontext for no reason. I think I am missing something. I don't see any co-ordination in this implementation... And how do thing "rollback" if something goes wrong?


回答1:


Don't use another UoW/repository abstraction layer

As OP correctly pointed out, Entity Framework (similar to e.g. NHibernate and other ORMs) already provide an abstraction of the database for you with both a transactional "unit of work" and "repositories" that are available to you.

The extra UoW / repository abstraction layer is an anti-pattern, that should be avoided at all cost. There are numerous problems with it, the most important of them being:

  • they prevent you from using the full power of the underlying ORM (lazy load, eager load, complex queries, ....)
  • if they want to provide any added benefits beyond simple CRUD, they will be leaky (i.e reflect the capabilities present in the underlying ORM).

But, but, but ...

I need to be able to unit test by mocking my repositories

No, you don't. Just use a database with content specific for your test for that. Use an in-memory database (e.g. SQLite, Effort, ...) if you want this to be faster.

EF does not enforce business logic which is not expressed in data relationships ... To enforce this type of logic, you have to build a OUW/Repository/both of some sort around the EF context.

No, you should't. To implement your business logic in an infrastructure abstraction layer such as a unit of work or repository is just plain wrong.

  • Valuable business logic belongs in domain entities, domain services, domain commands or for long running business processes, sagas.
  • Simple validations (i.e. not null, value between x and y) don't: those should be solved at your system interface boundaries.

Also note that simple CRUD style actions without any valuable business logic don't need to go through all the "layer hoops", i.e. avoid this pattern:

  1. Database → Entity without behavior → DTO → View Model → View
  2. Edit fields
  3. View → View Model → DTO → Entity without behavior → Database

Just load it directly from your ORM in your controller in the "View Model" shape needed for the view, and save it directly from your controller.

On abstractions

Unnecessary abstractions and layer hoops such as these are evil. They obfuscate your code, tie your hands, leak, increase your code size and therefore the amount of bugs in your code without providing any added value.

Use abstractions when they offer you added value, e.g. when you need them in solving cross-cutting concerns, capturing/managing recurring patterns in your architecture, ...

Creating abstractions for the sake of abstracting is a waste of time.




回答2:


I've already written extensively on this here, but I'll summarize for your benefit. Yes, Entity Framework already implements the UoW (DbContext) and repository (DbSet) patterns. There is no benefit in re-implementing them yet again. In fact, there's great detriment as it adds significantly to the maintenance overhead of your project.

Why did Microsoft include this in the introductory tutorials? Honestly, I'm not sure, but it was a mistake that has plagued countless new MVC developers, myself included when I was just getting started.

There is benefit in some sort of abstraction, such that your project is not dependent on any one particular way of getting data. However, this abstraction should return the specific data that your actions need, no more, no less. For lack of a better word, I refer to this as a "service", although Microsoft has grafted quite a different meaning onto that word via SOA. Simply, it's like you're just creating an API for your application to use, much as if you were creating a web API, only entirely code-based (not requiring an actual HTTP connection). This then goes into your DAL layer (class library or similar) that your project can reference.




回答3:


The thing about EF is that there is no business logic in the OUW or Repository functionality it exposes. If you call SaveChanges it will happily save all changes. However, it there is a requirement that when adding say a Widget the addition of a Frobber for the Widget is necessary you are out of luck (unless there is a FK dependency involved). For any bit of business logic which is not expressed in data relationships, EF out of the box does not enforce it.

To enforce this type of logic, you have to build a OUW/Repository/both of some sort around the EF context. That's the only reason you'd do it to my knowledge.




回答4:


unit of work and repository pattern has no concern with entity frame work. it is one of the design pattern. so it is used to make your code more readable, re-usable and efficient and also these pattern are used to achieve singelton (one time object instanciation) and also for avoid inversion of control.



来源:https://stackoverflow.com/questions/29972433/uow-and-repository-pattern-in-ef5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!