ngonzalezromero
ngonzalezromero

Reputation: 103

Entity Framework Core Update Many-to-many Object

I have this code to update a entity

 public async Task<User> UpdateAsync(User entity)
 {
      var userDb = await _context.User.Include(x => x.UserApplications).ThenInclude(xx =>
      xx.Application).Include(x => x.State).Include(x => x.UserProfiles).ThenInclude(x => 
      x.Profile).FirstOrDefaultAsync(x => x.UserName == entity.UserName && x.SecretKey == 
      entity.SecretKey && x.Email == entity.Email);


    userDb.FirstName = entity.FirstName;
    userDb.LastName = entity.LastName;
    userDb.State = await _context.State.FirstAsync(x => x.StateId == entity.State.StateId);

    userDb.UserProfiles.Clear();
    userDb.UserApplications.Clear();
    userDb.UserProfiles.AddRange(entity.UserProfiles); //ManyToMany
    userDb.UserApplications.AddRange(entity.UserApplications); //Many To Many
    _context.User.Update(userDb);
    await _context.SaveChangesAsync();
    return userDb;
}

Generate sql

Executed DbCommand (8ms) [Parameters=[@p0='?', @p1='?', @p14='?', @p2='?', @p3='?', @p4='?', @p5='?', @p6='?', @p7='?', @p8='?', @p9='?', @p10='?', @p11='?', @p12='?', @p13='?', @p15='?', @p16='?', @p17='?', @p18='?', @p19='?', @p20='?', @p21='?'], CommandType='Text', CommandTimeout='30'] INSERT INTO "Application" ("ApplicationId", "ApplicationName") VALUES (@p0, @p1); UPDATE "User" SET "ApiKeyId" = @p2, "Comment" = @p3, "CreationDate" = @p4, "Email" = @p5, "FirstName" = @p6, "IsOnLine" = @p7, "LastLoginDate" = @p8, "LastName" = @p9, "Password" = @p10, "SecretKey" = @p11, "StateId" = @p12, "UserName" = @p13 WHERE "UserId" IS NOT DISTINCT FROM @p14; DELETE FROM "UserApplication" WHERE "UserApplicationId" IS NOT DISTINCT FROM @p15; DELETE FROM "UserProfile" WHERE "UserProfileId" IS NOT DISTINCT FROM @p16; DELETE FROM "UserProfile" WHERE "UserProfileId" IS NOT DISTINCT FROM @p17; INSERT INTO "UserProfile" ("ProfileId", "UserId") VALUES (@p18, @p19) RETURNING "UserProfileId"; INSERT INTO "UserProfile" ("ProfileId", "UserId") VALUES (@p20, @p21) RETURNING "UserProfileId";

Why EF insert a new entity

  ( INSERT INTO "Application" ("ApplicationId", "ApplicationName")
  VALUES (@p0, @p1)) if only i need update the user?

Regards

User Class

public sealed class User
{
    public int UserId { get; set; }
    public string SecretKey { get; set; }
    public ApiKey Apikey { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
    public string Comment { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime LastLoginDate { get; set; } = DateTime.Now;
    public DateTime CreationDate { get; set; } = DateTime.Now;
    public bool IsOnLine { get; set; } = false;
    public State State { get; set; } = new State();
    public List<UserProfile> UserProfiles { get; set; } = new List<UserProfile>();
    public List<UserApplication> UserApplications { get; set; } = new List<UserApplication>();


}

UserApplication Class

 public class UserApplication
{
    public int UserApplicationId { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
    public int ApplicationId { get; set; }
    public Application Application { get; set; }
}

Upvotes: 1

Views: 370

Answers (2)

Thomas Boby
Thomas Boby

Reputation: 789

When you call

    userDb.UserApplications.Clear();

you clear every UserApplication, which is presumably the principal for the Application. Cascade delete is removing the Application so EF knows it has to reinsert it.

Upvotes: 1

Rafael Ribeiro
Rafael Ribeiro

Reputation: 188

I have been in this situation a some time ago.

In my situation, the insert was happening because the object I was adding had the primary key (Id) = 0. So EF always understood as a new row.

Can be a possibility.

Upvotes: 0

Related Questions