430

The single best reason to not use the repository pattern with Entity Framework? Entity Framework already implements a repository pattern. DbContext is your UoW (Unit of Work) and each DbSet is the repository. Implementing another layer on top of this is not only redundant, but makes maintenance harder. People follow patterns without realizing the purpose of ...


98

I don't see any reason for the Repository pattern to not work with Entity Framework. Repository pattern is an abstraction layer you put on your data access layer. Your data access layer can be anything from pure ADO.NET stored procedures to Entity Framework or an XML file. In large systems, where you have data coming from different sources (database/XML/...


44

Here's one take from Ayende Rahien: Architecting in the pit of doom: The evils of the repository abstraction layer I'm not sure yet whether I agree with his conclusion. It's a catch-22 - on the one hand, if I wrap my EF Context in type-specific repositories with query-specific data retrieval methods, I am actually able to unit test my code (sort of), which ...


16

The reason why you probably would do that is because it's a little redundant. Entity Framework gives you a wealth of coding and functional advantages, that's why you use it, if you then take that and wrap it in a repository pattern you are throwing those advantages away, you might as well be using any other data access layer.


14

In theory I think it makes sense to encapsulate the database connection logic to make it more easily reusable, but as the link below argues, our modern frameworks essentially take care of this now. Reconsidering the Repository Pattern


7

Re: "UOW tracks the elements that needs be changed, and repository contains the logic to persist those changes, but... who call who?" You understand the basic responsibilities of these classes. You say that each of the articles, that you've read, connects them together in different ways. This implies that the decision about "who calls who" is up to you. I'...


6

A very good reason to use the repository pattern is to allow the separation of your business logic and/or your UI from System.Data.Entity. There are numerous advantages to this, including real benefits in unit testing by allowing he use of Fakes or Mocks.


6

static ObjectContext class This is actually even worse than what you think. The ObjectContext class is not thread safe so even if you manage to get what you think is good synchronization, (without actually locking) you will still be throwing exceptions all the time in a multi-user environment. The ADO.NET team recommends using a new ObjectContext every ...


6

This is a common problem in testing. You have class A that uses class B that uses class C. So how do you test class B? You must be able to mock class C and pass it to class B before you can test B. In your case, we're talking about UnitOfWork depending on ICustomerRepository. The trick is this: if UnitOfWork is responsible for instantiating an ...


5

In general a unit of work corresponds with a database transaction. So from that perspective: BEGIN TRANSACTION -- do stuff COMMIT TRANSACTION Databases are very advanced with how they handle this. Any data you read after the BEGIN TRANSACTION statement is "locked" to any other thread (note that you can override this behavior in your SELECT statement ...


5

One reason the Unit Of Work pattern can be efficient, as the paragraph states, is because it can batch several operations and reuse resources. Using Unit of Work provides a context that can contain several operations into a single transaction that might otherwise be difficult to operate on together. Also, not only can the Unit of Work use a single prepared ...


5

Please note that I only have minor experience with the .NET framework and that this answer only relates to the architecture part of your question. As far as I understood it, you are basically applying the following architectural patterns in your application: Layers: It seems you have a persistence layer (Repository Pattern), a business logic layer and a ...


5

The immediate problem I see here that it becomes hard to unit test the "UnitOfWork" with mock repositories. What if the line repoItem = new Repository<TEntity, object>(Context); needs to be replaced by ... new MockRepository for a meaningful test? So in case UnitOfWork just needs one or two, maybe 3 repos, you could try to inject them in the ...


4

I just finished an article today about the repository pattern (with sample implementations). The thing with most .NET ioc containers is that they support scoping. That is, they can create objects with a limited lifetime. That works very well with HTTP applications since the scope is the same as the lifetime of a HTTP request. If you use ASP.NET MVC you ...


4

Your question is a little odd, sort of like asking why you need the unit of work pattern when you could just use objects. Monads are more fundamental than your question implies. You can use a monad as part of the implementation of the unit of work pattern, but that's not a sufficient description of the solution. You would also need to describe which monad ...


4

If you follow the pattern described in the article, then you would only need to change MockRepository or MockUnitOfWork if the respective interface (IRepository and IUnitOfWork) changes. The idea behind this is that you can unit-test all the other parts of your application without needing access to a real database (and without the trouble that data ...


3

Your repositories need to depend on the DbContext and not vice versa. Also, you don't have to implement Unit of Work since the DbContext already implements it. You could do it like this: public interface IRepository<T> { T ReadOne(object key); // so on, so forth... } public class Repository<T> : IRepository<T> where T : class, ...


3

Yes, there are many problems with this approach. First, The EF DBContext is not thread safe. If you make it static, then multiple users hitting this DbContext at the same time can cause data corruption, particularly if you're saving any items to the database. Even if it's read-only, you still have to deal with the fact that objects get inserted into the ...


3

What you want is to instantiate one ObjectContext per web request, regardless of how many different database accesses might be required by that request. And you don't want to share it with any other web requests, or else you'll get your multithreading issues. The approach I take is based on this blog post: "LINQ-to-SQL: the multi-tier story" by Steve ...


3

Ideally things would vary according to the rule of common sense. Martin Fowler talks about a unit as a class (plus related classes in some cases) and IMHO a unit should be a useful lump of code, this may be a single method where a method is quite complex, or a whole class as classes are the means of dividing a system into manageable components. A single ...


3

There is no "one size fits all" answer to where you should put the boundaries of your SUT. The optimal size of a SUT for unit-testing depends on a lot of factors, including The language and toolchain you are working with (how many errors can be detected by static analysis/compiling the code) The complexity of the product you are making How familiar the ...


2

What you're describing is a really common pattern where instead of injecting the object of interest you want to inject an object that can create instances of the object of interest. You might call it a factory. If you are using Autofac it is baked in by simply injecting Func<T> (to create instances of T). I'm pretty sure Castle Windsor has this same ...


2

The methods are most commonly given to the UOW interface (which is normally constructed via a factory). You typically call methods on a UOW interface from command pattern class(es) / facade. Since UOW simply defers database IO until later (to prevent you from having long-running transactions or multiple calls to the database that may be unnecessary), ...


2

Services which just change model properties don't sound like data services to me. They sound like model functions, and could (probably should) be in one model class or another. Maybe those methods weren't put in a model class because it wasn't clear where they belonged. I avoid circular references between model classes, so I let owning models depend on ...


2

If you stop worrying about your data and start thinking about your domain model it will become much more clear. I now see you are stuck with unit of work, repositories, data operations, layers and adapters but you forget about your business. What I would suggest to do is to have proper rich domain model designed and have a service layer that will play ...


2

I have went through this loop in the last few years, Unit Of Work, wrapping of repo's all calling Entity Framework. You end up with a lot of pointless repository classes (with associated interface), probably wrapping a generic base repo class with a Unit Of Work on top that has lots of properties which expose the repo's. And yes, you are correct, Entity ...


2

DBContext only provides you with a UoW pattern if you code up all the changes in one go yourself, which is pretty much no different to writing a single query in SQL yourself. You should use the UoW pattern if performance is your concern - writing a single hit to the DB is better than writing 1 hit per change. However, most people use an ORM for RAD tooling ...


2

In the desktop application I am currently working at we solved similar problems by introducing an event mechanism, centered around a global "Event Manager". We have got a handful of "main business objects" (~10 different types), and whenever one dialog changes a business object, it raises a "change" event, including the type and the ID of the related object (...


2

A fairly simple extension of the Unit of Work pattern would be do create an interface (call it ITransactionItem, perhaps) that contains commit and rollback methods. You could then make each of your unit of work objects implement that, along with any object that performs related functions, like your file operation. A new, top level unit of work would then ...


2

You mention "EF auto generated classes", which suggest you're using a DB-first approach. But you mentioned in the comments that you're open to anything, so I want to suggest switching to a Code First approach. Robert Harvey's answer isn't wrong, I simply want to offer another viable solution to the problem. Note: I don't know much about EF Core ...


Only top voted, non community-wiki answers of a minimum length are eligible