2010-03-03 3 views
3

Après avoir créé un nouvel objet (Foo), je définis la clé (BarId) pour une propriété d'association EntityRef (Bar). Je veux ensuite insérer le nouvel objet dans la base de données, et être en mesure d'accéder à l'objet enfant paresseux chargé par la suite.InsertOnSubmit ne joint pas?

Malheureusement, la propriété de chargement paresseux renvoie null après l'appel à InsertOnSubmit(). Il retourne l'objet correct si je joins à la place Attach() l'objet au contexte de données, cependant.

Code est ici qui insère avec succès mon nouvel objet dans la base de données, mais ne pas correctement la configuration de chargement paresseux pour l'enfant propriété Bar:

var foo = new Foo(); 
foo.BarId = 123; 
context.GetTable<Foo>().InsertOnSubmit(foo); 
foo.Bar.Something(); // throws NullReferenceException 

Ici, l'objet de la barre est correctement chargé:

var foo = new Foo(); 
foo.BarId = 123; 
context.GetTable<Foo>().Attach(foo); 
foo.Bar.Something(); // method is called on lazy-loaded Bar object 

appel avant d'attacher InsertOnSubmit provoque ce dernier de jeter un « Impossible d'ajouter une entité qui existe déjà » exception.

Donc, est-ce un bug dans LINQ-to-SQL, où les objets insérés ne sont pas correctement attachés au contexte de données?

Comment résoudre ce problème?

+0

Lors de l'utilisation de InsertOnSubmit, vous avez besoin de SaveChanges pour soumettre le nouvel objet au magasin de données. Cela pourrait être le problème, puisque la création d'un nouvel élément de données n'associe pas intrinsèquement un contexte de données (à un chargement paresseux de) jusqu'à ce que l'objet soit peuplé par le contexte (je pense). –

+0

Je vois. Malheureusement, j'ai construit une couche de sécurité au-dessus de mon contexte de données qui vérifie les permissions d'objet/utilisateur avant d'appeler SubmitChanges(). Ce code doit accéder à certaines propriétés de mes objets, y compris ceux qui sont chargés paresseux. Si c'est une bonne idée est discutable, mais c'est ce que je dois travailler maintenant. – MikeWyatt

+0

@NickLarsen: Je viens de tester cela, et vous avez raison. Le chargement paresseux fonctionne après avoir appelé SubmitChanges(). – MikeWyatt

Répondre

3

Je définirais la propriété Bar au lieu de la propriété BarId de votre classe Foo. À mon avis, ce que Linq-to-sql fait de mal ici, c'est d'avoir la propriété BarId en premier lieu. Il n'ajoute aucune valeur et va à l'encontre des principaux principes de la POO. Donc, je voudrais changer votre code à quelque chose comme ceci:

var foo = new Foo(); 
foo.Bar = //get bar with id: 123; 
context.GetTable<Foo>().InsertOnSubmit(foo); 
foo.Bar.Something(); 
+0

Cela a du sens. Le seul inconvénient est maintenant que j'ai besoin d'ajouter une petite quantité de complexité supplémentaire à mon code en demandant explicitement Bar, plutôt que de simplement définir un ID. – MikeWyatt

+0

Oui, mais à mon avis, c'est beaucoup mieux. Il semble beaucoup mieux d'un point de vue OO. Regardez simplement les autres ORM comme EF ou nhibernate. –