3 votes

Entity framework 4 CRUD création d'erreurs

J'ai 3 tables liées dans ma base de données.

Ferme ----> CulturesFerme <----- Cultures

Je cherche à mettre à jour une entité ferme avec une collection de cultures mais je rencontre des problèmes. Je travaille là-dessus sans succès depuis des heures maintenant, donc toute aide serait grandement appréciée.

L'erreur que je reçois est la suivante:

L'objet ne peut pas être attaché car il est déjà dans le contexte de l'objet. Un objet ne peut être réattaché que s'il est dans un état inchangé.

Ma logique de mise à jour est la suivante (mes excuses pour la grande quantité de code. Je veux juste être aussi clair que possible):

            bool isNew = false;
            Farm ferme;

            // Logique d'insertion ou de mise à jour.
            if (viewModel.Farm.FarmId.Equals(Guid.Empty))
            {
                ferme = new Farm
                {
                    FarmId = Guid.NewGuid(),
                    RatingSum = 3,
                    RatingVotes = 1
                };
                isNew = true;
            }
            else
            {
                ferme = this.ReadWriteSession
                       .Single(x => x.FarmId == viewModel.Farm.FarmId);

            }

            // Modifier/Ajouter les propriétés.
            ferme.Name = viewModel.Farm.Name;
            ferme.Owner = viewModel.Farm.Owner;
            ferme.Address = viewModel.Farm.Address;
            ferme.City = viewModel.Farm.City;
            ferme.Zip = viewModel.Farm.Zip;
            ferme.WebAddress = viewModel.Farm.WebAddress;
            ferme.PhoneNumber = viewModel.Farm.PhoneNumber;
            ferme.Hostel = viewModel.Farm.Hostel;
            ferme.Details = viewModel.Farm.Details;
            ferme.Latitude = viewModel.Farm.Latitude;
            ferme.Longitude = viewModel.Farm.Longitude;
            ferme.Weather = viewModel.Farm.Weather;

            // Ajouter ou mettre à jour les cultures.
            string[] cropIds = Request.Form["crop-token-input"].Split(',');
            List allCrops = this.ReadWriteSession.All().ToList();

            if (!isNew)
            {
                // Supprimer toutes les relations précédentes entre cultures/fermes.
                ferme.Crops.Clear();
            }

            // Parcourir et ajouter des cultures.
            foreach (Crop crop in allCrops)
            {
                foreach (string id in cropIds)
                {
                    Guid guid = Guid.Parse(id);
                    if (crop.CropId == guid)
                    {
                        ferme.Crops.Add(crop);
                    }
                }
            }

            if (isNew)
            {
                this.ReadWriteSession.Add(ferme);
            }
            else
            {
                this.ReadWriteSession.Update(ferme);
            }
            this.ReadWriteSession.CommitChanges();

Mon code de mise à jour dans le ReadWriteSession est assez simple (GetSetName renvoie simplement le nom du type à partir de sa PropertyInfo.):

    /// 
    /// Met à jour une instance du type spécifié.
    /// 
    /// L'instance du type donné à ajouter.
    /// Le type d'entité pour lequel fournir la méthode.
    public void Update(T item) where T : class, new()
    {
        this.context.AttachTo(this.GetSetName(), item);
        this.context.ObjectStateManager.ChangeObjectState(item, EntityState.Modified);
    }

4voto

Carvelis Points 1952

Vous ajoutez des objets Crop existants (de la liste allCrops) à la nouvelle Farm. Lorsque vous connectez une nouvelle entité à une existante, la nouvelle entité se connecte automatiquement au contexte. C'est pourquoi vous obtenez une erreur lorsque vous essayez de connecter la Farm au contexte une deuxième fois.

L'instruction Add(farm) dans votre code n'est même pas nécessaire pour connecter la Farm au contexte, et si vous avez une Farm existante chargée à partir du contexte, elle est déjà attachée au contexte.

L'ensemble de votre instruction if (isNew) est inutile. Entity framework suit l'état de l'objet lui-même, donc vous n'avez pas besoin de définir l'état modifié.

3voto

AbdouMoumen Points 2748

Vous n'avez pas besoin d'attacher l'objet "ferme" à la fin, car il est déjà attaché en tant que modifié lorsque vous changez l'une de ses propriétés. essayez de supprimer l'instruction else à la fin:

if (isNew)
{
   this.ReadWriteSession.Add(farm);
}

J'espère que cela vous aidera :)

2voto

Ladislav Mrnka Points 218632

Le problème se trouve dans votre méthode de mise à jour. Vous ne pouvez pas attacher l'instance Farm car vous l'avez chargée à partir du même contexte, elle est donc déjà attachée et vous n'avez pas besoin d'appeler votre méthode Update du tout car les modifications apportées aux objets attachés sont suivies automatiquement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X