Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6355399
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T22:45:28+00:00 2026-05-24T22:45:28+00:00

I still have some confusion with the Repository Pattern. The primary reason why I

  • 0

I still have some confusion with the Repository Pattern. 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 and 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.

Here is an example of my situation:

I have 3 tables in the database: Group, Person, and GroupPersonMap. GroupPersonMap is a link table and just consists of the Group and Person primary keys. I created an EF model of the 3 tables with VS 2010 designer. EF was smart enough to assume GroupPersonMap is a link table so it doesn’t show it in the designer. I want to use my existing domain objects instead of EF’s generated classes so I turn off code generation for the model.

My existing classes that matches the EF model are as follows:

public class Group
{
   public int GroupId { get; set; }
   public string Name { get; set; }

   public virtual ICollection<Person> People { get; set; }
}

public class Person
{
   public int PersonId {get; set; }
   public string FirstName { get; set; }

   public virtual ICollection<Group> Groups { get; set; }
}

I have a generic repository interface like so:

public interface IRepository<T> where T: class
{
    IQueryable<T> GetAll();
    T Add(T entity);
    T Update(T entity);
    void Delete(T entity);
    void Save()
}

and a generic EF repository:

public class EF4Repository<T> : IRepository<T> where T: class
{
    public DbContext Context { get; private set; }
    private DbSet<T> _dbSet;

    public EF4Repository(string connectionString)
    {
        Context = new DbContext(connectionString);
        _dbSet = Context.Set<T>();
    }

    public EF4Repository(DbContext context)
    {
        Context = context;
        _dbSet = Context.Set<T>();
    }

    public IQueryable<T> GetAll()
    {
        // code
    }

    public T Insert(T entity)
    {
        // code
    }

    public T Update(T entity)
    {
        Context.Entry(entity).State = System.Data.EntityState.Modified;
        Context.SaveChanges();
    }

    public void Delete(T entity)
    {
        // code
    }

    public void Save()
    {
        // code
    }
}

Now suppose I just want to map an existing Group to an existing Person. I would have to do something like the following:

        EFRepository<Group> groupRepository = new EFRepository<Group>("name=connString");
        EFRepository<Person> personRepository = new EFRepository<Person>("name=connString");

        var group = groupRepository.GetAll().Where(g => g.GroupId == 5).First();
        var person = personRepository.GetAll().Where(p => p.PersonId == 2).First();

        group.People.Add(person);
        groupRepository.Update(group);

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. I must use DbSet‘s Attach method to tell EF that the Person already exists in the database so just create a map between Group and Person in the GroupPersonMap table.

So in order to attach Person to the context I must now add an Attach method to my IRepository:

public interface IRepository<T> where T: class
{
    // existing methods
    T Attach(T entity);
}

To fix the primary key constraint error:

EFRepository<Group> groupRepository = new EFRepository<Group>("name=connString");
EFRepository<Person> personRepository = new EFRepository<Person>(groupRepository.Context);

var group = groupRepository.GetAll().Where(g => g.GroupId == 5).First();
var person = personRepository.GetAll().Where(p => p.PersonId == 2).First();

personRepository.Attach(person);
group.People.Add(person);
groupRepository.Update(group);

Fixed. Now I have to deal with another issue where Group is being UPDATE’d in the database every time I create a Group/Person map. This is because in my EFRepository.Update() method, the entity state is explicitly set to Modified'. I must set the Group's state toUnchangedso theGroup` table doesn’t get modified.

To fix this I must add some sort of Update overload to my IRepository that does not update the root entity, or Group, in this case:

public interface IRepository<T> where T: class
{
    // existing methods
    T Update(T entity, bool updateRootEntity);
}

The EF4 implentation of the Update method would look something like this:

T Update(T entity, bool updateRootEntity)
{
   if (updateRootEntity)
      Context.Entry(entity).State = System.Data.EntityState.Modified;
   else
      Context.Entry(entity).State = System.Data.EntityState.Unchanged;

    Context.SaveChanges();
}

My question is: 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. Thanks for reading this long post

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T22:45:29+00:00Added an answer on May 24, 2026 at 10:45 pm

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I still have some confusion about this thing. What I have found till now
I've used ( and still use ) mercurial and git. I have some repos
Ok I am still learning this... I have Googled and done some research but
I'm using rails_admin which use devise. Some words still displays in english. I have
I have some confusion about how to use AtlasLabel. It seems Label consume a
There might be similar questions but I still have some parts that I couldn't
I've read some docs about the .NET Garbage Collector but i still have some
im currently learning python (in the very begining), so I still have some doubts
Why can't I browse deeper into the folder, I still have some folders there:
I have some old code (an old but still maintained VB6 application) that from

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.