MVC 3 EF 4.1 dbContext - Suppression d'un objet de données un-à-plusieurs avec une relation de clé étrangère non nullable

Je suis en utilisant MVC 3, 4.1 EF, et dbContext. J'ai besoin de savoir comment supprimer une entité dans un-à-plusieurs avec un non nullable de clé étrangère.

Quand j'ai Retirer l'enfant de l'entité et de l'exécuter SaveChanges j'obtiens l'erreur:

L'opération a échoué: La relation ne peut pas être changé parce que l'un ou plusieurs de la clé étrangère propriétés est pas les valeurs null. Lorsqu'une modification est apportée à une relation, la clé étrangère de la propriété est définie sur une valeur null. Si la clé étrangère ne prend pas en charge les valeurs null, une nouvelle relation doit être définie, la clé étrangère de la propriété doit être attribuée à une autre valeur non nulle, ou sans rapport avec l'objet doit être supprimé.

D'autres posts, je comprends que l'utilisation de Supprimer(entité) les marques de l'entité pour les supprimer. Pendant SaveChanges, EF définit la clé étrangère à Null et l'erreur ci-dessus se produit.

J'ai trouvé quelques posts qui utilisent DeleteObject sur l'entité enfant plutôt que de le Retirer; cependant, la DeleteObject approche semble avoir été abandonné à cause de plus de dbContext et DbSet.

J'ai trouvé un poste qui suggèrent que la modification de l'EDMX de clé étrangère de la relation à accepter les valeurs null. La modification de l'EDMX est très bien, mais à chaque fois qu'une mise à Jour du Modèle de Base de données est effectuée, ces changements s'nuked et doit être appliqué de nouveau. N'est pas optimal.

Un autre post propose la création d'un proxy de l'entité avec la clé étrangère relations configuré pour accepter les valeurs null, mais je ne comprends pas cette approche. Il semble souffrir du même problème que la modification de l'EDMX dans le fait que le contexte est automatiquement mis à jour lorsque des modifications à la EDMX sont enregistrés.

Mon modèle simplifié est:

public partial class User
{
    public User()
    {
        this.UserContacts = new HashSet<UserContact>();
    }

    public long userId { get; set; }
    public string userEmail { get; set; }
    public string userPassword { get; set; }
    public string userFirstName { get; set; }
    public string userLastName { get; set; }
     . . .
    public virtual Country Country { get; set; }
    public virtual State State { get; set; }
    public virtual ICollection<UserContact> UserContacts { get; set; }
}

}

public partial class UserContact
{
    public long userContactId { get; set; }
    public long userContactUserId { get; set; }
    public long userContactTypeId { get; set; }
    public string userContactData { get; set; }

    public virtual ContactType ContactType { get; set; }
    public virtual User User { get; set; }
}

La userContactUserId et userContactTypeId sont nécessaires étrangères-clés.

Dans le dbContext contenant à la fois des Utilisateurs et UserContact sont DbSet.

J'ai un ViewModel pour l'Utilisateur et un ViewModel pour UserContact comme suit

public class UserContactViewModel
{
    [HiddenInput]
    public long UserContactId { get; set; }

    [HiddenInput]
    public long UserContactUserId { get; set; }

    [Display(Name = "Contact")]
    [Required]
    public string ContactData { get; set; }

    [Required]
    public long ContactType { get; set; }

    [HiddenInput]
    public bool isDeleted { get; set; }

}

    public class MyProfileViewModel
    {

        [HiddenInput]
        public long UserId { get; set; }

        [Required]
        [Display(Name = "First Name")]
        [StringLength(100)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(100)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
        ....
        public IEnumerable<UserContactViewModel> Contacts { get; set; }

}

Lors de l'enregistrement des modifications dans le profil utilisateur, je boucle sur la liste des UserContactViewModel entités afin de déterminer celles qui ont été ajoutés, modifiés ou supprimés.

                    foreach (var c in model.Contacts)
                    {
                        UserContact uc = usr.UserContacts.Single(con => con.userContactId == c.UserContactId);
                        if (uc != null)
                        {
                            if (c.isDeleted == true)  //Deleted UserContact
                            {
                                ctx.UserContacts.Remove(uc);  //Remove doesn't work
                            }
                            else  // Modified UserContact
                            {
                                uc.userContactData = c.ContactData;
                                uc.userContactTypeId = c.ContactType;
                                ctx.Entry(uc).State = EntityState.Modified;
                            }
                        }
                        else  //New UserContact
                        {
                            usr.UserContacts.Add(new UserContact { userContactUserId = model.UserId, userContactData = c.ContactData, userContactTypeId = c.ContactType });
                        }
                    }

J'apprécierais toute aide.

source d'informationauteur Max