2009-05-29 7 views
0

Je dois administrer c'est assez drôle même si je pense que je comprends pourquoi :) J'ai créé un UnitTest pour ajouter une entrée de blog pour essayer Alex suggestion sur mes problèmes d'héritage. Maintenant, je tombe sur un autre.EF4 - Ajout d'une entrée de blog se plaint de Profil?

[TestMethod] 
public void UserCanAddBlogEntry() 
{ 
    var context = new EntityContext(Options.LazyLoading); 

    var user = (from u in context.Users 
        .Include("Blog.BlogEntries") 
       where u.Id == 1 
       select u).FirstOrDefault(); 

    BlogEntry entry = new BlogEntry(); 
    entry.Header = "Test Entry"; 
    entry.Text = "Test Text blah blah blah"; 
    entry.CreatedAt = DateTime.Now; 
    entry.Blog = user.Blog; 

    user.Blog.BlogEntries.Add(entry); 
    context.SaveChanges(); 

    Assert.IsTrue(user.Blog.BlogEntries.Count > 0); 
} 

provoque l'exception:

Échec UserCanAddBlogEntry Zirzle.UnitTests
Méthode d'essai UserCanAddBlogEntry jeté exception: System.InvalidOperationException: fixup relation non valide détectée dans la propriété de navigation 'utilisateur' de l'entité du type "Profil".

Vous ne savez pas quel est le problème avec cette image. Si j'ajoute .Include ("Profil") dans la requête get puis enregistrer les changements ne se plaint plus. J'ai essayé d'ajouter une fin de relation à 0.1 pour le profil mais cela n'a pas fonctionné non plus. Aucune suggestion? Je suppose que la pile déborde de l'expert EF personnel pourrait avoir une explication :)

Répondre

1

Eh bien celui-ci est intéressant.

Je suppose que Blog.BlogEntries est l'inverse de BlogEntry.Blog

Je suppose aussi que toutes les propriétés sur toutes les classes sont virtuelles, de sorte que le EF proxy les classes peux.

Compte tenu de ces hypothèses certains objets seront proxies (user et user.Blog) parce que le ObjectContext les construit et certains ne seront pas soumises à proxy (entry) parce que vous les avez créés vous-même.

cours font automatiquement corriger par proxy, c.à garder les deux extrémités d'une relation de synchronisation

Ainsi faisant cela sur un user.Blog approximé:

user.Blog.BlogEntries.Add(entry) 

définit automatiquement entry.Blog à user.Blog au en même temps pour garder les deux relations synchronisées pour vous.

D'autre part parce que entry n'est pas ce qu'un proxy:

entry.Blog = user.Blog 

ne fera pas fixup. Donc, dans ce code, vous faites essentiellement deux fois la moitié de la réparation. Nous devrions probablement gérer cette situation avec élégance, mais évidemment, nous ne le ferons pas, j'en parlerai avec l'équipe.

Cela dit tout ce que je vous suggère de faire quelque chose d'un peu plus simple:

// notice there is no need to get the User just the users blog 
var blog = (from u in context.Users 
      where u.Id == 1 
      select u.Blog).Single(); 

et juste faire ceci:

BlogEntry entry = new BlogEntry(); 
entry.Header = "Test Entry"; 
entry.Text = "Test Text blah blah blah"; 
entry.CreatedAt = DateTime.Now; 
entry.Blog = blog; 
//because BlogEntry inherits from Post if I remember your model 
context.Posts.Add(entry); 
context.SaveChanges(); 

Cela devrait fonctionner.

Alex

+0

Toutes vos hypothèses étaient exactes. Cependant, je reçois toujours des problèmes avec le correctif en utilisant votre suggestion: Méthode de test UserCanAddBlogEntry a levé l'exception: System.InvalidOperationException: correction de relation non valide détectée dans la propriété de navigation 'BlogEntries' de l'entité du type 'Blog'. – mhenrixon

+0

Hmm ... Je suis un peu déconcerté en ce moment. Au lieu de entry.Blog = blog laissez-moi savoir ce qui se passe si vous essayez blog.BlogEntries.Add (entrée) à la place. –

+0

J'ai fait ce que vous avez suggéré, sauf pour une chose. J'ai créé une méthode AddEntry (entrée d'entrée) qui vient d'ajouter une entrée à l'IList comme recommandé dans le poco posts ado.net blog a. Devrait être dans la classe User à l'avenir. Il y a deux problèmes, faire ce que vous avez suggéré est de me donner un problème de correction. Faire ce que vous avez suggéré dans le commentaire me donne une exception nullreference. Je pense que c'est le proxy qui crée une sorte de problème mais sérieusement je ne sais même pas si c'est un bug. Je veux dire que j'ai dit que je peux prendre soin de moi, ça me dit de le faire. Je ne vais pas exposer le contexte de cette façon de toute façon. – mhenrixon

Questions connexes