A problem I ran into that you might encounter when working with Entity Framework 4.1 involved already existing entities being re-inserted into the database when they were being associated with new entities. Many times this would result in an error when committing the transaction (which, in retrospect), is probably the best outcome to that kind of scenario, since uninhibited insertion of duplicate data is truly on the catastrophic level of things).

Given the complexity of Entity Framework, I’ll assume that there’s more than one set of circumstances that can lead to unwanted entity re-insertions. That aside, the reason why I was getting these excessive inserts turned out to be very simple, resulting in a simple solution.

To paint a quick picture, let’s say you have a Group entity:

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

Ok, not very exciting there. Now, let’s add a User entity to the mix.

    public class User
    {
      public int Id { get; set; }
      public string Name { get; set; }
      public ICollection<Group> Groups { get; set; }
    }

As you can see above, User entities maintain associations with one or more groups. The groups are maintained independently of users; new users, if assigned to groups, will always be assigned to groups that of course exist prior to the creation of said user. This is only common sense people.

Going back to the issue described at the beginning of the article, I would get the issue to occur when creating a new User, assigning it one or more groups, and then saving it to the database. The error was a DbUpdateException, and the error message more or less reflected that I was trying to insert those Groups I associated to my new User as if they were new Groups! A SQL Profiling session confirmed this, where I was able to observe this egregious act.

So, if this is happening to you, the reason why may be because your Group instances are not from the currently active DbContext. If you are maintaining short-lived DbContexts, and perhaps caching some of this data to avoid unnecessary round trips, you may fall victim to this habit.

Your associated entity instances need to be from the same data context that you’re adding the new primary entity into. If you are sporting cached instances of entities, one way you can solve your issue is by attaching the old instances to the new context. I have had mixed results doing this, and I have not had the time to properly investigate proper attachment routines with EF 4.1. In the short term, I found it to be unreliable, or at least less than clear. The quickest route to safety was to simply re-fetch the associated entities.

Of course this is all just common sense — of course your associated entities need to be from the same data context as your new entity. The point is, is that it can be easy to make this mistake if you are trying to keep detached entities floating around.

Have you encountered similar excessive-insertion-type errors, but due to different reasons? I’d be interested to hear about it.

Matt Weber

I'm the founder of Bad Echo LLC, which offers consulting services to clients who need an expert in C#, WPF, Outlook, and other advanced .NET related areas. I enjoy well-designed code, independent thought, and the application of rationality in general. You can reach me at matt@badecho.com.

  4 Responses to “Entity Framework: Unwanted Insertions of Existing Entities (DbUpdateException)”

  1. of course your associated entities need to be from the same data context as your new entity

    of course… because the fact that they have the same primary keys isnt a tell at all …

    this entity framework is killing me

  2. Exactly, why can it not detect this from the primary key ? So many weird things in EF not seen in other ORM frameworks

  3. When I have a global cache with entities of type Email then the User entity will have only the Email_Id instead of a reference to Email entity.

  4. Thanks! This solved a bug we had today

Leave a Reply to erlend Cancel reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
   
© 2012-2013 Matt Weber. All Rights Reserved. Terms of Use.