Entity framework creates duplicate entities

asp.net-mvc-4 asp.net-web-api c# entity-framework

Question

Edit

Please take a look at my screencast of my issue if you have time. You can find it at here.

I have the code below, which should execute AddOrUpdate functionality, but all existing entries are instead recreated, resulting in several USAs and New Yorks. EntityState is being transferred from the client so that if data changes on the client, the client will update the EntityState property and transmit it to the server.

    [HttpPost, HttpGet, HttpPut]
    public HttpResponseMessage SaveRecord(RecordViewModel record)
    {
        var model = Mapper.Map<Record>(record);

        if (!ModelState.IsValid)
        {
            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
        }

        db.Attach(model);

        try
        {
            db.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
        }

        return Request.CreateResponse(HttpStatusCode.OK, Mapper.Map<RecordViewModel>(model));
    }

The following function is what I'm associating entities with.

    public void AttachAndMarkAs<T>(T entity, EntityState state, Func<T, object> id) where T : class
    {
        var entry = Entry(entity);

        if (entry.State == EntityState.Detached)
        {
            var set = Set<T>();

            T attachedEntity = set.Find(id(entity));

            if (attachedEntity != null)
            {
                var attachedEntry = Entry(attachedEntity);

                if (state != EntityState.Unchanged)
                {
                    attachedEntry.CurrentValues.SetValues(entity);
                    attachedEntry.State = state;
                }
            }
            else
            {
                entry.State = state;
            }
        }
    }

which is sent through the following:

    public void Attach(City entity)
    {
        if (entity != null)
        {
            Attach(entity.Country);

            AttachAndMarkAs(entity, entity.EntityState ?? EntityState.Added, instance => instance.Id);
        }
    }

    public void Attach(Country entity)
    {
        if (entity != null)
        {
            AttachAndMarkAs(entity, entity.EntityState ?? EntityState.Added, instance => instance.Id);
        }
    }

Given that the EntityState data are accurate, I'm not sure which section of the code deals with adding entities as opposed to updating them.

1
2
6/24/2013 8:31:22 PM

Accepted Answer

ZZZ_tmp
3
6/24/2013 8:41:52 PM

Popular Answer

When modifying the parent entity's state programmatically, you need to be aware of how Entity Framework handles referenced and child entities.

Check out this article to see how things stand in a variety of situations.

You might assume that all the relevant entities in the example below will be set asModifiied :

using (var context = new BloggingContext())
{
    context.Entry(existingBlog).State = EntityState.Modified;
    // Do some more work... 
    context.SaveChanges();
}

Actually though, they won't. According to the article:

If you have multiple entities that need to be marked Modified you should set the state for each of these entities individually.

Finally, here is how you should approach theAddOrUpdate case particular when yourPrimaryKey is anInt :

using (var context = new BloggingContext())
{
   context.Entry(blog).State = blog.BlogId == 0 ? EntityState.Added : EntityState.Modified;

   context.SaveChanges();
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow