2009-12-02 4 views
0

J'ai une table, disons STUDENTS, qui est liée un-à-plusieurs à une autre table, CLASSES. J'ai créé un formulaire ASP.Net pour prendre l'entrée d'un nouvel étudiant, y compris la sélection d'une des classes à partir d'une zone de liste déroulante. C'est une application petite mais à plusieurs niveaux, et j'ai commencé à utiliser le framework d'entité. L'EF a donc généré des classes pour ces deux tables. Sur Submit, je construis un objet STUDENT et le remets à mon contrôleur de données pour les insertions, mises à jour, etc.Maître/Détail avec Entity Framework

Dans la table STUDENTS, j'ai un CLASSID qui est un FK à la table CLASSES. De retour dans la journée, quand je ferais l'insertion aux ÉTUDIANTS je prendrais le SelectedValue de la zone de liste déroulante et le colleriez dans le champ ClassId. Cependant, avec l'EF, l'objet STUDENT n'a pas ce champ ID. Au lieu de cela, il a un champ CLASS, qui est une instance complète de cette classe. Lorsque le nouvel objet STUDENT est construit, ce champ CLASS est null. Je veux le peupler avec la classe choisie par l'utilisateur dans le combo.

Je ne peux pas le laisser nul, et je ne peux pas simplement mettre l'ID dedans. J'ai essayé de faire une récupération de cet enregistrement de classe et de l'utiliser, mais j'ai une erreur que je ne peux pas utiliser le même objet avec deux contextes différents. Qu'est-ce que je suis vraiment censé faire ici?

Répondre

2

Vous pouvez définir la propriété EntityKey de ClassReference:

Student.ClassReference.EntityKey = new EntityKey("myModel.ClassSet", "ID", classId); 

EDIT

Voici comment ajouter étudiant (je ne peux pas vérifier maintenant, mais il devrait fonctionner):

newStudent.BClassReference.EntityKey = new EntityKey("FormsEntities.BClasses", "BClassId", 13); 

FormsEntities fe = new FormsEntities(); 
fe.AddToStudents(newStudent); 
fe.SaveChanges(); 
+3

Je voulais juste ajouter que dans EF4 l'ID FK sera exposée et vous n'avez pas besoin d'utiliser EntityKey. – jfar

+0

LukLed, votre méthode a fonctionné pour moi. J'aime cette méthode car elle ne nécessite pas que je retourne à la base de données pour obtenir un enregistrement complet. Je connais déjà le PK, je veux juste l'utiliser. Je dois admettre que je ne sais pas ce qui se passe exactement dans votre code. Avant, j'ai essayé d'initialiser l'objet newStudent.BClass, puis d'ajouter une nouvelle clé d'entité, qui ne fonctionnait pas. Cette propriété qui ajoute le mot "Reference" à la fin du nom d'objet semble faire le travail, indépendamment de savoir si la propriété BClass est null. Aussi, comme dans l'autre solution de Craig, tout doit se passer avec UN seul contexte. –

+0

EntityReference est utilisé pour fonctionner sur les propriétés de navigation qui ne sont pas encore chargées. Vous devriez également regarder la propriété IsLoaded et Load() méthode qui est utilisée pour obtenir l'entité à partir de DB: http://msdn.microsoft.com/en-us/library/bb297956.aspx – LukLed

2

Pourquoi ne pas commencer en faisant les choses facilement?

using (var fe = new FormsEntities()) 
{ 
    newStudent.BClass = fe.BClasses.Where(bc => bc.BClassId == 13).First(); 
    fe.AddToStudents(newStudent); 
    fe.SaveChanges(); 
} 

Ne pas Muck autour avec EntityKey s jusqu'à ce que vous obtenez les bases de travail. Je pense que "optimiser" une sauvegarde est en grande partie une perte de temps.

+0

J'ai essayé cela dès le début, en utilisant une syntaxe différente , où je l'ai récupéré et l'ai mis dans l'objet newStudent. Lorsque j'ai essayé de le sauvegarder, j'ai reçu une exception: l'objet était déjà attaché à un contexte différent. Je vais essayer à nouveau en utilisant votre syntaxe, peut-être que je vais avoir plus de chance. Je ne sais pas "optimiser" la sauvegarde; Je veux juste effectuer la sauvegarde. –

+0

Vous utilisiez probablement> 1 contexte (instance 'FormsEntries'), alors. Je suggère d'utiliser seulement un à la fois autant que possible. Rend les choses beaucoup plus simples. –

+0

Craig, votre méthode a fonctionné. Je pense que j'ai compris pourquoi le mien n'a pas. J'ai eu la même idée, mais je faisais les GET dans une fonction différente, pour des raisons de séparation. Quand je l'ai fait, j'ai utilisé un tout nouveau contexte. Donc j'irais chercher le BClass en utilisant "GetClass (id)" et ensuite appeler une fonction différente, avec un contexte différent, pour sauver l'étudiant. J'obtiendrais "Un objet d'entité ne peut pas être référencé par plusieurs instances de IEntityChangeTracker."Quand j'utilise ta syntaxe, ou même la mienne, toutes au même endroit avec le même contexte (FormsEntities), tout fonctionne bien, merci pour ton aide. –