Robert
Robert

Reputation: 4406

What is the proper way to update Many To Many with EF?

I am curious as to what the proper way to update a list of entities at one time is.

    public ActionWas Update(IEnumerable<surcharge_template> templates)
    {
        try
        {
            var templatesToBeUpdated = _context.surcharge_template.Where(x => templates.Select(template => template.st_key).Contains(x.st_key));
           //Right here I need to map all of the differences from the original templates
           //to the new templates
            _context.Entry(templatesToBeUpdated).State = EntityState.Modified;
        }
        catch (Exception ex)
        {
            return _exceptionConverter.Convert(ex);
        }
        _context.SaveChanges();
        return ActionWas.Successsful;
    }

I put a comment at the point where I am not sure the way to handle this. I get the original templates from the database and then I need to map them, then commit and save.

So what is the proper way to map them?

UPDATE:

I would like to do this with EF only making one call to the database. Enumerating the list would cause multipe update statements.

Upvotes: 5

Views: 260

Answers (2)

Miguel
Miguel

Reputation: 3952

The Attach method don't attach sub-entities. In order to do this, you need to Attach all the dependents target that you want to update. You can use GraphDiff to update a full graph without attaching the entities. The usage is something like this:

using (var context = new TestDbContext())  
{
    // Update the company and state that the company 'owns' the collection Contacts.
    context.UpdateGraph(company, map => map
        .OwnedCollection(p => p.Contacts, with => with
            .AssociatedCollection(p => p.AdvertisementOptions))
        .OwnedCollection(p => p.Addresses)
    );

    context.SaveChanges();
}

This is a brief introduction to the framework.

Hope this help!

Upvotes: 0

Miguel
Miguel

Reputation: 3952

You don't need to map the current entity. You can use a syntax like the SQL Update instead.

Use EntityFramework.Extended

//update all tasks with status of 1 to status of 2
context.Templates.Update(
    t => t.StatusId == 1, 
    t2 => new Template {StatusId = 2});

This is only a workaround, at the end if you need to do different changes for each Template you will need to modify the entity status.

Upvotes: 1

Related Questions