Repository pattern with EF4 CTP5?

"YOU AND THE ART OF ONLINE DATING" is the only product on the market that will take you step-by-step through the process of online dating, provide you with the resources to help ensure success. Get it now!

You need to step back and think about what the repository should be doing. A repository is used for retrieving records, adding records, and updating records. The repository you created barely handles the first case, handles the second case but not efficiently, and doesn't at all handle the 3rd case.

You need to step back and think about what the repository should be doing. A repository is used for retrieving records, adding records, and updating records. The repository you created barely handles the first case, handles the second case but not efficiently, and doesn't at all handle the 3rd case.

Most generic repositories have an interface along the lines of public interface IRepository where T : class { IQueryable Get(); void Add(T item); void Delete(T item); void CommitChanges(); } For retrieving records, you can't just call the whole set with AsEnumerable() because that will load every database record for that table into memory. If you only want Users with the username of username1, you don't need to download every user for the database as that will be a very large database performance hit, and a large client performance hit for no benefit at all. Instead, as you will see from the interface I posted above, you want to return an IQueryable object.

IQuerables allow whatever class that calls the repository to use Linq and add filters to the database query, and once the IQueryable is run, it's completely run on the database, only retrieving the records you want. The database is much better at sorting and filtering data then your systems, so it's best to do as much on the DB as you can. Now in regards to inserting data, you have the right idea but you don't want to call SaveChanges() immediately.

The reason is that it's best to call Savechanges() after all your db operations have been queued. For example, If you want to create a user and his profile in one action, you can't via your method, because each Insert call will cause the data to be inserted into the database then. Instead what you want is to separate out the Savechanges() call into the CommitChanges method I have above.

This is also needed to handle updating data in your database. In order to change an Entity's data, Entity Framework keeps track of all records it has received and watches them to see if any changes have been made. However, you still have to tell the Entity Framework to send all changed data up to the database.

This happenes with the context.SaveChanges() call. Therefore, you need this to be a separate call so you are able to actually update edited data, which your current implementation does not handle. Edit: Your comment made me realize another issue that I see.

One downfall is that you are creating a data context inside of the repository, and this isn't good. You really should have all (or most) of your created repositories sharing the same instance of your data context. Entity Framework keeps track of what context an entity is tracked in, and will exception if you attempt to update an entity in one context with another.

This can occur in your situation when you start editing entities related to one another. It also means that your SaveChanges() call is not transactional, and each entity is updated/added/deleted in it's own transaction, which can get messy. My solution to this in my Repositories, is that the DbContext is passed into the repository in the constructor.

– Chuck Norris Feb 21 at 13:30 Updated answer for the first part. Calling context.Set.XXX is correct, and is how I do it in my repositories. – KallDrexx Feb 21 at 13:38 @KallDrexx I do a web application, if everybody is going to use the same context, and somebody will call SaveChanges() that's gonna be really messy, isn't it?

– Chuck Norris Feb 21 at 13:47 @Omu: You should have one context per request. Most of DI libraries support this behavior. – LukLed Feb 21 at 13:56 1 You can have repositories created via IoC, but you still need to have the repositories take a DbContext in as a constructor parameter, and then instantiate that as well via IoC.

That will allow your DbContext to be shared across the web request – KallDrexx Feb 21 at 14:44.

I may get voted down for this, but DbContext already is a repository. When you expose your domain models as collection properties of your concrete DbContext, then EF CTP5 creates a repository for you. It presents a collection like interface for access to domain models whilst allowing you to pass queries (as linq, or spec objects) for filtering of results.

If you need an interface, CTP5 doesn't provide one for you. I've wrapped my own around the DBContext and simply exposed the publicly available members from the object. It's an adapter for testability and DI.

I'll comment for clarification if what I said isn't apparently obvious.

Please do elaborate! – Sean Gough May 3 at 12:53 If you're going for DDD then you'd want to create a Repository that exposes an aggregate root. Say a Customers repository.

Use your imagination for all the associations a customer has and how deep that object graph is. All of those items are available on the EF context object you create in the form of your DbSet properties. If you wrap the context object inside of a object that is a repository for customers, all you're doing is passing through to the DBSet properties.

If you're not going for DDD, you're not going to care about aggregate roots and the context is actually sufficient by itself. – Joshua Ramirez Jun 16 at 17:13 The context by itself is sufficient because it exposes DbSet properties, remember? Take a look at the DbSet declarations on MSDN.

Doesn't that look like a repository? ;) That's a not-so-well-advertised-non-accident. So, ok, maybe it's got a few extras, but if that bothers you just wrap it around a repository interface/adapter.

– Joshua Ramirez Jun 16 at 17:18.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions