coolhand
coolhand

Reputation: 2061

Adding item to collection navigation property in EF Core

I have a Project class that contains a collection of AppUsers

public class Project
{
    public int ProjectID { get; set; }

    [Required(ErrorMessage = " Please enter a project name")]
    public string Name { get; set; }

    [Required(ErrorMessage = " Please enter a project description")]
    public string Description { get; set; }

    public virtual ICollection<AppUser> ProjectManagers { get; set; }

    public bool UserIsAlreadyPM(string userId)
    {
        foreach(AppUser user in this.ProjectManagers)
        {
            if(user.Id == userId)
            {
                return true;
            }
        }
        return false;
    }
}

My AppUser class

public class AppUser : IdentityUser
{
    //add properties here later
}

I want to be able to have the capability for any particular AppUser to be within the ProjectManagers of more than one Project. I add the AppUser to any Project.ProjectManagers via my repository method:

public void AddProjectManager(int projectID, AppUser user)
{
      Project proj = context.Projects.FirstOrDefault(p => p.ProjectID == projectID);
      if(proj != null)
      {
          proj.ProjectManagers.Add(user);
          context.SaveChanges();
      }
}

This works the first time the AppUser is added to a Project.ProjectManagers collection. However, this will not work if I attempt to add them to any other Project.ProjectManagers collection. If they are assign to any subsequent Project.ProjectManagers I get an primary key error because they are already in the database under a different project.

"SqlException: Violation of PRIMARY KEY constraint 'PK_AppUser'. Cannot insert duplicate key in object 'dbo.AppUser'. The duplicate key value is (xxxx)."

Upvotes: 3

Views: 5581

Answers (1)

TanvirArjel
TanvirArjel

Reputation: 32069

Please write your code as follows:

public void AddProjectManager(int projectID, AppUser user)
{
        Project proj = context.Projects.Include(p => p.ProjectManagers)
                              .FirstOrDefault(p => p.ProjectID == projectID);

        if(!proj.ProjectManagers.Any(pm => pm.Id = user.Id)) // <-- Here check that `AppUser` already not in Project's `ProjectManagers` collection
        {
            AppUser appUser =  context.AppUsers.FirstOrDefault(p => p.Id== user.Id);
            if(appUser != null) // <-- Confirm that the `AppUser` you are trying to add to Project's `ProjectManagers` collection is already exist in database
            {
                proj.ProjectManagers.Add(appUser);
                context.SaveChanges();
            }
        }
 }

Upvotes: 3

Related Questions