2010-03-30 7 views
1

J'ai une entité Linq to Sql qui a un entité EntitySet. Dans ma vue, j'affiche l'entité avec ses propriétés plus une liste modifiable pour les entités enfants. L'utilisateur peut ajouter et supprimer dynamiquement ces entités enfants. DefaultModelBinder fonctionne correctement jusqu'à présent, il lie correctement les entités enfants. Maintenant, mon problème est que je ne peux tout simplement pas Linq To Sql pour supprimer les entités enfants supprimées, il va heureusement ajouter de nouvelles, mais pas supprimer celles supprimées. J'ai activé la suppression en cascade dans la relation de clé étrangère et le concepteur Linq To Sql a ajouté l'attribut "DeleteOnNull = true" aux relations de clé étrangère. Si je supprime manuellement une entité enfant comme ceci:ASP.NET MVC 2: Mise à jour d'une entité Linq-To-SQL avec un EntitySet

Ceci supprimera l'enregistrement enfant de la base de données. Mais je ne peux pas le faire fonctionner pour un objet lié à un modèle. J'essayé ce qui suit:

// this does nothing 
public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities 
{ 
    var obj2 = _repository.GetObj(id); // obj2 has 6 child entities 
    if(TryUpdateModel(obj2)) //it sucessfully updates obj2 and its childs 
    { 
     _repository.SubmitChanges(); // nothing happens, records stay in DB 
    } 
    else 
     ..... 

    return RedirectToAction("List"); 
} 

et cela jette un InvalidOperationException, j'ai un allemand OS, donc je ne sais pas exactement ce que le message d'erreur est en anglais, mais il dit quelque chose le long des lignes de ce que les besoins de l'entité une version (Ligne d'horodatage?) ou aucune politique de vérification de mise à jour. J'ai mis UpdateCheck = "Jamais" à chaque colonne à l'exception de la colonne de la clé primaire.

public ActionResult Update(MyObject obj) 
{ 
    _repository.MyObjectTable.Attach(obj, true); 
    _repository.SubmitChanges(); // never gets here, exception at attach 
} 

J'ai lu beaucoup de choses sur les problèmes similaires « » avec LINQ to SQL, mais il semble que la plupart de ces « problèmes » sont en réalité par la conception. Est-ce que j'ai raison de penser que cela ne fonctionne pas comme si je m'attendais à ce que ça marche? Dois-je vraiment parcourir manuellement les entités enfants et les supprimer, les mettre à jour et les insérer manuellement? Pour un objet aussi simple, cela peut fonctionner, mais j'ai l'intention de créer des objets plus complexes avec des EntitySets imbriqués, etc. Ceci est juste un test pour voir ce qui fonctionne et ce qui ne fonctionne pas. Jusqu'à présent, je suis déçu par Linq To Sql (peut-être que je ne comprends pas). Serait l'Entity Framework ou NHibernate un meilleur choix pour ce scénario? Ou pourrais-je rencontrer le même problème?

+0

Cela vous ennuie de partager le texte en allemand? –

+0

Bien sûr! Le message d'exception est le suivant: "Eine Entität kann nur als geändert und ohne den ursprünglichen Zustand angefügt werden, wenn sie ein Versionselement deklariert oder über keine Richtlinie für die Überprüfung auf Updates verfügt." – Simon

+0

Cela arrive-t-il toujours ou juste quand vous utilisez .Attach? –

Répondre

0

Il certainement travailler dans Entity Framework qui vient avec .NET 4 (je fais des choses semblables dans la version RC)

Cela n'explique pas l'exception mais:

Vous devriez disposer le ObjectContext qui est (le plus probablement) enveloppé dans votre dépôt. Le contexte met en cache les éléments et ne doit être utilisé que pour une seule unité de travail.

Essayez d'utiliser un modèle comme:

public ActionResult Update(int id, MyObject obj) // obj now has 4 child entities 
{ 
    using(var repository = CreateRepository()) 
    { 
     var obj2 = _repository.GetObj(id); 
     if(TryUpdateModel(obj2)) 
     { 
      repository.SubmitChanges(); 
     } 
     else 
      ..... 
    } 

    return RedirectToAction("List"); 
} 

Lors de l'extraction des éléments, créez un nouveau référentiel ainsi. Ils sont peu coûteux à créer et à éliminer, et doivent être éliminés le plus rapidement possible.

+0

Actuellement, je crée le référentiel dans le constructeur du contrôleur, donc je m'attends à ce qu'il ne vive que pour une seule requête, ou ai-je tort? Est-ce qu'un contrôleur vit plus longtemps? (Je commence juste avec MVC et LinqToSql) Je l'ai essayé avec l'instruction using dans l'action, mais étrangement il continue à ajouter de nouveaux enregistrements pour les objets enfants. Je continuerai à enquêter. Merci pour l'instant! – Simon

+0

Bon point, ajoutez quelques points d'arrêt: Où le référentiel est créé, dans '.Update' et dans' .List'. Si le constructeur n'est pas exécuté deux fois, vous avez un problème possible. –

+0

Ok Je viens de cocher ceci et le dépôt est en cours de création pour chaque requête – Simon

Questions connexes