2017-05-11 1 views
0

Utilisation de la première approche du code MVC5.mvc 5 code premier utilisateur en tant que clé étrangère - Comment enregistrer des données

Je n'ai pas modifié le magasin de l'utilisateur, ajouté une propriété appelée Nom dans ApplicationUser Class. Il semble donc que la façon suivante: -

public class ApplicationUser : IdentityUser 
{ 
    [Required] 
    [StringLength(100)] 
    public string Name { get; set; } 

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
    { 
     // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
     // Add custom user claims here 
     return userIdentity; 
    } 
} 

J'ai une classe de la société, qui ressemble à ci-dessous: -

public class Company 
{ 
    public int Id { get; set; } 

    [Required] 
    [StringLength(255)] 
    public string Name { get; set; } 
} 

Une entreprise a certainement plus d'un utilisateur, mais dans ma conception un utilisateur peut être associé à plus d'une entreprise. J'ai donc une classe distincte pour CompanyUsers qui se présente comme suit: -

public class CompanyUsers 
{ 
    public int Id { get; set; } 

    [Required] 
    public virtual Company Company { get; set; } 

    [Required] 
    public virtual ApplicationUser User { get; set; } 
} 

Maintenant, quand j'enregistrer un utilisateur, je suis la mise en son rôle et aussi les entreprises que l'utilisateur appartient, mais il semble que le UserManager défini dans le code intégré a déjà enregistré. Donc, après avoir ajouté les données CompanyUsers, quand j'appelle applicationDbContext.Savechanges(), cela échoue car l'utilisateur a déjà été enregistré dans la base de données. Pouvez-vous me dire comment je peux y arriver? Je peux le faire dans une autre logique, comme après avoir créé un utilisateur, dans une fonction distincte assigner des utilisateurs à la société (s), mais je veux connaître la solution dans ces circonstances. Aussi, je peux redessiner le magasin de l'utilisateur.

Ma fonction de registre modifié AccountController est la suivante: -

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Name = model.Name }; 
      var result = await UserManager.CreateAsync(user, model.Password); 
      if (result.Succeeded) 
      { 
       await UserManager.AddToRoleAsync(user.Id, model.Role); 
       var userCompany = new CompanyUsers 
       { 

        Company = _context.Companies.First(t => t.Id == model.CompanyId), 
        User = user 
       }; 

       try 
       { 
        _context.CompanyUsers.Add(userCompany); 
        _context.SaveChanges();// throws exception 
       } 
       catch (DbEntityValidationException dbEx) 
       { 
        foreach (var validationErrors in dbEx.EntityValidationErrors) 
        { 
         foreach (var validationError in validationErrors.ValidationErrors) 
         { 
          Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage); 
         } 
        } 
       } 
       return RedirectToAction("UserViewAll", "Manage"); 
      } 
      AddErrors(result); 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 

Je viens de commencer le code mvc première approche, donc je ne peux pas comprendre si vous utilisez le jargon technique, merci à l'avance pour votre aide !! !!!

+0

Votre classe d'entreprise doit contenir un 'IEnumerable virtuel '. En outre, je recommande d'ajouter le rôle de l'utilisateur à la classe 'CompanyUser'. De cette façon, un utilisateur peut avoir différents rôles dans différentes entreprises. – nurdyguy

+0

c'est génial, pouvez-vous s'il vous plaît expliquer pourquoi la classe entreprise besoin virtuel IEnumerable ? – 3not3

+0

Eh bien, la société a des utilisateurs non? Ensuite, ils devraient être sur l'objet. En d'autres termes, lorsque vous avez 'company123', vous devriez être capable de faire' company123.CompanyUsers' pour obtenir la liste des utilisateurs de cette société. Si le chargement paresseux est disponible, il le remplira automatiquement. Si le chargement paresseux n'est pas disponible, vous devrez effectuer l'appel pour le peupler, mais de toute façon, il sera plus naturel. – nurdyguy

Répondre

1

Essayez d'ajouter le code suivant dans le bloc if (result.Succeeded):

_context.Entry(user).State = EntityState.Unchanged; 

La question semble être que le contexte de données dans cette méthode ne connaît pas l'état de l'entité user parce que UserManager.CreateAsync utilise un autre contexte. L'entité est attachée lorsque vous l'affectez à l'entité CompanyUser, puis ce contexte de données tente de l'enregistrer en tant que nouvelle entité.