Updating the many-to-many collection with EF code

I am using EF Code First with the following configuration

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<UserProfile>()
        .HasMany(x => x.TeamLeaders)
        .WithMany()
        .Map(m => m.MapLeftKey("UserId")
        .MapRightKey("TeamLeaderId")
        .ToTable("UserTeamLeaders"));
}

TeamLeaders is an ICollection of users, that is, it is self-regulation between many relationships.

In plain English, a user can have more than one team leader. This configuration seems correct, as it creates a table of links to the FK / PK match, as you would expect.

I have an MVC4 application that allows me to edit, add and remove team leaders from a collection.

In my controller, I initially had the following:

    var original = context.UserProfiles
        .Include("TeamLeaders")
        .Single(x => x.UserId == model.UserId);

    context.Entry(original).CurrentValues.SetValues(model);

However, this last line was not able to mark the TeamLeaders collection as updated, and when I called SaveChanges (), no changes were recorded.

CopyProperties User, , , :

    var original = context.UserProfiles
        .Include("TeamLeaders")
        .Single(x => x.UserId == model.UserId);

    //context.Entry(original).CurrentValues.SetValues(model);

    original.CopyProperties(model);

, SaveChanges , .

- , ? ,

+5
1

TeamLeaders original , , . SaveChanges, EF DELETE INSERT . :

var original = context.UserProfiles
    .Include("TeamLeaders")
    .Single(x => x.UserId == model.UserId);

original.TeamLeaders.Clear();
foreach (var teamLeader in model.TeamLeaders)
{
    var user = context.UserProfiles.Find(teamLeader.UserId);
    if (user != null)
        original.TeamLeaders.Add(user)
}
context.SaveChanges();

Find , . , .

, :

var original = context.UserProfiles
    .Include("TeamLeaders")
    .Single(x => x.UserId == model.UserId);

original.TeamLeaders.Clear();
foreach (var teamLeader in model.TeamLeaders)
{
    var user = context.UserProfiles.Local
        .SingleOrDefault(o => o.UserId == teamLeader.UserId);
    if (user == null)
    {
        user = new User { UserId = teamLeader.UserId };
        context.UserProfiles.Attach(user);
    }
    original.TeamLeaders.Add(user)
}
context.SaveChanges();

original .

BTW: Include EF Code First:

Include(u => u.TeamLeaders)

using System.Data.Entity; , .

+3

All Articles