Entity Framework: Travailler avec des objets détachés et attachés

c# entity-framework

Question

Tout d’abord, laissez-moi préciser ce que je voudrais faire. Supposons que j'ai trois types d’ EntityObject , MetaData , Data1 et Data2 . Comme on pouvait s'y attendre, MetaData contient une référence à une instance de Data1 et Data2 . Maintenant, pour chaque MetaData , je peux calculer une value .

Jusqu'ici si simple. J'aimerais maintenant que l'utilisateur puisse jouer avec diverses combinaisons de Data1 et Data2 et voir quelle value il peut obtenir. Cela nécessite évidemment la création d'instances de MetaData . Maintenant, si je ne veux pas manipuler la base de données avec toutes ces entrées de MetaData , j'aimerais créer les objets d'entité dans le contexte en mémoire sans appeler un SaveChanges() pour le réécrire dans la base de données. Cependant, cela pose un problème que chaque fois que je tente d'accéder aux Data1 et Data2 références de la mémoire en MetaData , je me retrouve à l'exception suivante:

InvalidOperationException n'est pas gérée

La requête source pour cette entité EntityCollection ou EntityReference ne peut pas être renvoyée lorsque l'objet associé est dans un état ajouté ou détaché et n'a pas été extrait à l'origine à l'aide de l'option de fusion NoTracking.

Si je fais ce qui est suggéré et "envoie" l'objet à DB, je me retrouve avec le problème d'encombrement.

Quoi qu'il en soit, le code de culpabilité ressemble à ceci:

MetaData temp = MetaData.CreateMetaData(0);

MetaData.Data1 = <existing Data1 from context>;
MetaData.Data2 = <existing Data2 from context>;

//Exception here
if (!MetaData.Data1Reference.isLoaded)
    MetaData.Data1Reference.Load();

Il semble que ce gars a eu un problème similaire.

Réponse acceptée

IsLoaded n'est pertinent que pour les propriétés d'instances matérialisées à partir d'une base de données. Comme vous l'avez découvert, il ne renvoie pas d'informations utiles pour les instances qui n'ont pas été matérialisées à partir d'une base de données.

Par conséquent, vous devriez changer la façon dont vous testez si vous voulez appeler Load (). Si vous savez que vous allez utiliser des instances de MetaData que vous avez uniquement créées en mémoire et non matérialisées à partir d'une base de données, vous pouvez écrire un code comme celui-ci:

if ((temp.EntityState != System.Data.EntityState.Added) && 
    (!temp.Data1Reference.IsLoaded)) temp.Data1Reference.Load();

Je passe en revue certaines subtilités, ici. Pour commencer, EntityState est déclaré avec FlagsAttribute, il peut donc contenir Added sans être égal à Added. En outre, rien de cela n'est nécessaire si Data1Reference n'est pas null, vous pouvez donc simplement le tester en premier. Le fait est que vous pouvez écrire du code qui convient à votre situation, mais il doit prendre en compte l'état complet de temp, pas seulement ses propriétés.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow