Repository Pattern with Entity Framework 4.1 and Parent/Child Relationships

The primary reason why I want to use this pattern is to avoid calling
EF 4.1 specific data access operations from the domain. I’d rather
call generic CRUD operations from a IRepository interface. This will
make testing easier

No it will not make your testing easier. You exposed IQueryable so your repository is not unit testable.

if I ever have to change the data access framework in the future, I
will be able to do so without refactoring a lot of code.

No you will have to change a lot of code anyway because you exposed IQueryable and because EF / ORM is leaky abstraction – your upper layer expects some behavior happens magically inside your ORM (for example lazy loading). Also this is one of the most odd reasons to go for repository. Simply choose the right technology now and use it to get the bets of it. If you have to change it later it means either that you did a mistake and chose the wrong one or requirements have changed – in either case it will be a lot of work.

But this doesn’t work because EF thinks Person is new, and will try to
re-INSERT the Person into the database which will cause a primary key
constraint error.

Yes because you are using a new context for each repository = that is wrong approach. Repositories must share the context. Your second solution is not correct as well because you put your EF dependency back to the application – repository is exposing the context. This is usually solved by second pattern – unit of work. Unit of work wraps the context and unit of work forms the atomic change set – SaveChanges must be exposed on unit of work to commit changes done by all related repositories.

Now I have an issue with the Group being UPDATE’d in the database
every time I want to create a Group/Person map.

Why do you change the state? You received entity from the repository so until you detached it there is no reason to call Attach and change the state manually. This all should happen automatically on attached entity. Simply call SaveChanges. If you are using detached entities then you must correctly set state for every entity and relation so in such case you will indeed needs some logic or update overloads to handle all scenarios.

Am I approaching this the right way? My Repository is starting to look
EF centric as I start to work with EF and the repository pattern.

I don’t think so. First of all you are not using aggregate roots. If you do you would immediately found that generic repository is not suitable for that. Repository for aggregate roots have specific methods per aggregate root to handle working with relations aggregated by the root. Group is not part of Person aggregate but GroupPersonMap should be so your Person repository should have specific methods to handle adding and removing groups from person (but not to create or delete groups themselves). Imo generic repository is redundant layer.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)