2010-11-09 4 views
1

Je suis actuellement encartage/mise à jour champs comme celui-ci (s'il y a une meilleure façon, s'il vous plaît dire - nous sommes toujours apprendre)Y a-t-il un détenteur d'objet de mise à jour sur Entity Framework?

public void UpdateChallengeAnswers(List<ChallengeAnswerInfo> model, Decimal field_id, Decimal loggedUserId) 
{ 
    JK_ChallengeAnswers o; 
    foreach (ChallengeAnswerInfo a in model) 
    { 
     o = this.FindChallengeAnswerById(a.ChallengeAnswerId); 
     if (o == null) o = new JK_ChallengeAnswers(); 

     o.answer = FilterString(a.Answer); 
     o.correct = a.Correct; 
     o.link_text = ""; 
     o.link_url = ""; 
     o.position = FilterInt(a.Position); 

     o.updated_user = loggedUserId; 
     o.updated_date = DateTime.UtcNow; 

     if (o.challenge_id == 0) 
     { 
      // New record 
      o.challenge_id = field_id; // FK 
      o.created_user = loggedUserId; 
      o.created_date = DateTime.UtcNow; 

      db.JK_ChallengeAnswers.AddObject(o); 
     } 
     else 
     { 
      // Update record 
      this.Save(); 
     } 
    } 

    this.Save(); // Commit changes 
} 

Comme vous pouvez le voir il y a 2 foisthis.Save() (sorcière invoque db.SaveChanges();)

quand Ajout nous plaçons le nouvel objet dans un place Holder avec la méthode AddObject, autrement dit, le nouvel objet est engage pas immédiatement et nous pouvons placer autant d'objets que nous voulons.

Mais quand il est une mise à jour, je dois d'abord enregistrer avant de passer à l'objet suivant, est-il une méthode que je peux utiliser pour, disons:

 if (o.challenge_id == 0) 
     { 
      // New record 
      o.challenge_id = field_id; 
      o.created_user = loggedUserId; 
      o.created_date = DateTime.UtcNow; 

      db.JK_ChallengeAnswers.AddObject(o); 
     } 
     else 
     { 
      // Update record 
      db.JK_ChallengeAnswers.RetainObject(o); 
     } 
    } 

    this.Save(); // Only save once when all objects are ready to commit 
} 

Donc, s'il y a 5 mises à jour, je ne ai pas besoin d'enregistrer dans la base de données 5 fois, mais seulement une fois à la fin.

Merci.

Répondre

2

Eh bien, si vous avez un objet qui est attaché au graphique, si vous modifiez valeurs de cet objet, l'entité est marquée comme modifiée.

Si vous faites simplement .AddObject, l'entité est marquée Ajouté.

Rien n'est encore arrivé - seulement mise en scène du graphique.

Ensuite,, lorsque vous exécutez SaveChanges(), EF convertira les entrées de l'OSM en requêtes de stockage pertinentes.

Votre code semble un peu étrange. Avez-vous débogué (et exécuté une trace SQL) pour voir ce qui est réellement exécuté? Parce que je ne vois pas pourquoi vous avez besoin de ce premier .Save, parce qu'en ligne avec mes points ci-dessus, depuis votre modification des entités dans les premières lignes de la méthode, une instruction UPDATE sera probablement toujours être exécuté, quel que soit l'ID .

Je vous suggère de refactoriser votre code pour gérer les nouveaux/modifiés en méthode séparée. (Idéalement par un dépôt)

+0

a obtenu, il n'y a pas besoin de tenir quoi que ce soit, l'EF sait que :) concernant refactoring .. dang! pas moyen, je peux refactoriser plus, si je refactorise ça j'aurai encore des doubles ... c'est parfait :) – balexandre

1

Extrait de Employee Info Starter Kit, vous pouvez envisager l'extrait de code comme ci-dessous:

public void UpdateEmployee(Employee updatedEmployee) 
     { 
      //attaching and making ready for parsistance 
      if (updatedEmployee.EntityState == EntityState.Detached) 
       _DatabaseContext.Employees.Attach(updatedEmployee); 
      _DatabaseContext.ObjectStateManager.ChangeObjectState(updatedEmployee, System.Data.EntityState.Modified); 
      _DatabaseContext.SaveChanges(); 
     } 
Questions connexes