2010-11-12 31 views
1

Ma question peut être mieux expliquée via un exemple de code. J'utilise POCO avec des proxies de suivi des changements qui sont générés par le générateur C# POCO par défaut. S'il vous plaît voir ci-dessous.Entité Framework POCO avec des clés étrangères

Supposons que vous ayez Movie, MusicDirector et Director dans la base de données et que la relation entre eux soit Director & MusicDirector peut diriger plusieurs films et un film ne peut avoir qu'un seul Director et MusicDirector. Comme je suis un nouvel utilisateur et que je ne peux pas publier d'images, voici ma structure db.

table Movie MovieID, Nom, MusicDirectorId, DirectorId

table directeur a DirectorId, Nom

table MusicDirector a MusicDirectorId, Nom

Voici le lien vers le diagramme. http://i.stack.imgur.com/ce49r.png. J'essaie d'insérer un nouveau film et le directeur et musicdirector "existe déjà" dans le DB. Voici mon code.

Movie movie = new Movie();    
     movie.Name = "Movie1"; 
     movie.Director = new Director() { Name = "DirectorA" };   
     movie.MusicDirector = new MusicDirector() { Name = "MusicDirectorA" }; 

     using (TestEFEntities ctx = new TestEFEntities()) 
     { 
      movie.Director = ctx.Directors.Where(x => x.Name == movie.Director.Name).FirstOrDefault(); 
      movie.MusicDirector = ctx.MusicDirectors.Where(x => x.Name == movie.MusicDirector.Name).FirstOrDefault();          
      ctx.Movies.AddObject(movie);      
      ctx.SaveChanges(); 
     } 

Maintenant, quand je le fais, record MusicDirector est ajouté à nouveau, même si elle est écrasée par l'enregistrement de la db. Vous pouvez penser pourquoi je garde cette ligne movie.Director = new Director() {Name = "DirectorA"}; Dans un premier temps, il s'agit d'une application Asp.net MVC où l'objet Movie est lié aux noms director et musicdirector que l'utilisateur ajoute. Donc, les 4 premières lignes sont faites implicitement par MVC et pensent que toutes les autres lignes sont dans la couche de service. Ai-je manqué quelque chose car c'est un scénario très basique et le cadre devrait le gérer? Bien sûr, une solution pour corriger ce problème est de créer un nouvel objet Movie et d'assigner les enregistrements de db que je ne veux pas faire car je dois copier toutes les propriétés de l'objet film envoyé par le contrôleur. Comment puis-je résoudre ce problème?

Cela fonctionne également correctement dans les entités auto-suivi. Est-ce une sorte de limitation à POCO et ce serait génial si quelqu'un pouvait expliquer le comportement?

Répondre

0

Si vous utilisez des POCO, votre code devrait fonctionner comme prévu. Alternativement, vous pouvez essayer de remplir les FK au lieu d'assigner l'objet entier comme ceci:

using (TestEFEntities ctx = new TestEFEntities()) 
{ 
    movie.DirectorID = ctx.Directors 
     .Where(x => x.Name == movie.Director.Name).First().DirectorID; 

    movie.MusicDirectorID = ctx.MusicDirectors 
     .Where(x => x.Name == movie.MusicDirector.Name).First().MusicDirectorID; 

    ctx.Movies.AddObject(movie);      
    ctx.SaveChanges(); 
} 
+0

J'utilise POCO et n'ai donc pas la propriété DirectorReference. – Jonna

+0

Oui, désolé, vous avez mentionné cela et je n'ai pas remarqué. Alors, comment peupler les FK comme je l'ai décrit dans ma réponse mise à jour? –

+0

Comment le feriez-vous en utilisant DbContext dans EF CTP 5 et avec "Ado.net DbContext generator"? Il n'y a pas de code de correction, donc la définition de DirectorId n'efface pas Director. Définit toujours movie.Director = null après avoir défini DirectorId comme ma seule option? – Jonna