Entity Framework: retrouver des objets récemment ajoutés au contexte

entity-framework

Question

J'utilise le framework d'entité et j'ai un problème avec "retrouver" les objets que je viens de créer ... en gros ça ressemble à ça:

string theId = "someId";

private void Test()
{
  using(MyEntities entities = new MyEntities())
  {
    EntityObject o = new EntityObject();
    o.Id = theId;
    entities.AddToEntityObject(o);
    CallSomeOtherMethod(entities);
  }
}

void CallSomeOtherMethod(MyEntities ents)
{
  EntityObject search = ents.EntityObject.FirstOrDefault(o => o.Id == theId);
  if(search == null) 
  {
    Console.WriteLine("wha happened???");
  }
}

(rien ne garantit que le code fonctionne d'ailleurs - c'est tout de ma tête)

Pourquoi la requête "ne trouve-t-elle pas" l'entité EntityObject qui vient d'être créée?

Si j'appelle SaveChanges () après AddToEntityObject, cela fonctionne (ce qui ne me surprend pas), mais pourquoi ne pas le récupérer correctement dans le cache?

Je suis toujours vert sur ce genre de choses alors j'espère qu'il y a une chose vraiment facile que je ne fais que négliger ...

Merci

Réponse acceptée

Cela se produit car ents.EntityObject.WhatEver interroge toujours la source de données. Ceci est une décision de conception. Ils le font de cette manière, car sinon, ils devraient exécuter la requête sur la source de données, sur le cache local, puis fusionner les résultats. Comme l’a souligné un des développeurs dans un blog (je ne me souviens plus où exactement), ils n’ont pas été en mesure de gérer cela de manière cohérente.

Comme vous pouvez l’imaginer, vous devez traiter correctement de nombreux cas de rebords. Vous pouvez simplement trouver un identifiant que vous avez créé localement, créé par quelqu'un d'autre dans la base de données. Cela vous obligerait à être prêt à gérer les conflits sur (presque) toutes les requêtes. Ils auraient peut-être pu créer des méthodes pour interroger le cache local et des méthodes pour interroger la source de données, mais cela n’est pas malin non plus.

Vous pouvez jeter un coup d’œil sur Chargement paresseux transparent pour Entity Framework . Ceci remplace le générateur de code normal et vous obtenez des entités qui renseignent automatiquement leurs collections d'entités associées et leurs références d'entités lors de l'accès. Cela évite tous les

if (!Entity.ReleatedEntities.IsLoaded)
{
   Entity.RelatedEntities.Load();
}

fragments de code. Et vous pouvez interroger les collections car elles sont toujours implicitement chargées. Mais cette solution n'est pas parfaite non plus. Il y a quelques problèmes. Par exemple, si vous créez une nouvelle entité et accédez à une collection d'entités associées, vous obtiendrez une exception car le code ne pourra pas extraire les entités associées de la base de données. Il y a aussi un problème concernant la liaison de données et il y en a peut-être d'autres que je ne suis pas au courant.

La bonne chose est que vous obtenez le code source et êtes en mesure de résoudre les problèmes vous-même et je vais examiner le premier problème si je trouve un peu de temps. Mais je suis tout à fait sûr que ce ne sera pas si facile à résoudre, car je m'attends à ce que certains cas ne touchent pas la base de données si l'entité vient d'être créée ne correspond pas au comportement attendu.


Réponse populaire

l'objet nouvellement ajouté est dans la source de données locale, car il n'est pas encore conservé dans la base de données. Vous pouvez donc dire EntityObject search = ents.EntityObject.FirstOrDefault(o => o.Id == theId) ?? ents.EntityObject.Local.FirstOrDefault(o => o.Id == theId);



Related

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