702 votes

Comment puis-je récupérer l'Id de l'entité insérée en utilisant Entity framework ?

J'ai un problème avec Entity Framework en ASP.NET. Je veux obtenir la valeur Id chaque fois que j'ajoute un objet à la base de données. Comment puis-je le faire ?

Selon Entity Framework la solution est :

using (var context = new EntityContext())
{
    var customer = new Customer()
    {
        Name = "John"
    };

    context.Customers.Add(customer);
    context.SaveChanges();

    int id = customer.CustomerID;
}

Cela ne permet pas d'obtenir l'identité de la table de la base de données, mais l'ID attribué à l'entité. Si nous supprimons un enregistrement de la table, l'identité de la graine ne correspondra pas à l'ID de l'entité.

2 votes

Si vous n'avez besoin que de l'identifiant pour l'utiliser dans une relation de clé étrangère, vous pouvez envisager de simplement définir la propriété de navigation de votre entité dépendante sur l'entité précédemment ajoutée. De cette façon, vous n'avez pas à vous soucier d'appeler SaveChanges tout de suite, juste pour avoir l'identité. Autres lectures aquí .

0 votes

Pour Entity Framework Core 3.0, ajoutez le paramètre acceptAllChangesOnSuccess comme true : await _context.SaveChangesAsync(true) ;

1140voto

Ladislav Mrnka Points 218632

C'est assez simple. Si vous utilisez des identifiants générés par la base de données (par exemple IDENTITY en MS SQL) il suffit d'ajouter une entité à ObjectSet y SaveChanges sur le sujet ObjectContext . Id sera automatiquement rempli pour vous :

using (var context = new MyContext())
{
  context.MyEntities.Add(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Yes it's here
}

Par défaut, Entity Framework suit chaque INSERT avec SELECT SCOPE_IDENTITY() lorsqu'il est généré automatiquement Id sont utilisés.

36 votes

Vous posez donc la mauvaise question. Si vous avez un problème avec une exception, vous devez poser la question en montrant votre exception (et l'exception interne) et le bout de code qui cause cette erreur.

4 votes

Assurez-vous que l'entité que vous ajoutez est une entité valide, par exemple, tout ce qui a une restriction de base de données de "not null" doit être rempli, etc.

4 votes

@LadislavMrnka : Qu'en est-il des propriétés de navigation de l'objet nouvellement créé ? Elles ne semblent pas se remplir automatiquement après l'enregistrement des modifications.

186voto

mark_h Points 2593

J'avais utilisé La réponse de Ladislav Mrnka Je suis cependant en train de poster ici parce que je l'ai mal utilisé (c'est-à-dire que je l'ai utilisé là où il n'était pas nécessaire) et j'ai pensé poster mes résultats ici au cas où des personnes chercheraient à "résoudre" le problème que j'avais.

Considérons un objet Order qui a une relation de clé étrangère avec Customer. Lorsque j'ai ajouté un nouveau client et une nouvelle commande en même temps, j'ai fait quelque chose comme ceci ;

var customer = new Customer(); //no Id yet;
var order = new Order(); //requires Customer.Id to link it to customer;
context.Customers.Add(customer);
context.SaveChanges();//this generates the Id for customer
order.CustomerId = customer.Id;//finally I can set the Id

Cependant, dans mon cas, cela n'était pas nécessaire car j'avais une relation de clé étrangère entre customer.Id et order.CustomerId.

Tout ce que j'avais à faire, c'était ça ;

var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer}; 
context.Orders.Add(order);
context.SaveChanges();//adds customer.Id to customer and the correct CustomerId to order

Maintenant, lorsque je sauvegarde les modifications, l'identifiant généré pour le client est également ajouté à la commande. Je n'ai pas besoin de ces étapes supplémentaires

Je suis conscient que cela ne répond pas à la question initiale, mais j'ai pensé que cela pourrait aider les développeurs qui ne connaissent pas EF à ne pas utiliser la réponse la plus votée pour quelque chose qui n'est peut-être pas nécessaire.

Cela signifie également que les mises à jour sont effectuées en une seule transaction, ce qui permet d'éviter les données orphelines (soit toutes les mises à jour sont effectuées, soit aucune ne l'est).

11 votes

Merci ! Conseil de bonne pratique IMPORTANT : var order = new Order{Customer = customer} ; Ceci montre la puissance d'Entity Framework pour assigner un objet lié et l'Id sera automatiquement mis à jour.

0 votes

Merci pour ces informations complémentaires à la réponse. Cela a été très utile pour économiser un aller-retour DB en utilisant EF.

0 votes

Merci beaucoup pour cela. C'est exactement ce que je cherchais. Je pensais juste qu'il pouvait y avoir un meilleur moyen que d'appeler deux fois "SaveChanges".

36voto

QMaster Points 384

Vous devez recharger l'entité après avoir enregistré les modifications. Parce qu'elle a été modifiée par un trigger de base de données qui ne peut pas être suivi par EF. Nous devons donc recharger l'entité à partir de la base de données,

db.Entry(MyNewObject).GetDatabaseValues();

Puis

int id = myNewObject.Id;

Regardez la réponse de @jayantha dans la question ci-dessous :

Comment puis-je obtenir l'Id de l'entité insérée dans Entity framework en utilisant defaultValue ?

La réponse de @christian à la question ci-dessous peut également vous aider :

Entity Framework Refresh context ?

2 votes

Bonjour, lorsque je fais ceci, j'obtiens l'erreur de compilation qui dit : ne peut pas résoudre les propriétés par exemple Id ou Name, pouvez-vous m'aider s'il vous plaît ?

1 votes

@MortezaAzizi Il semble qu'il s'agisse d'une erreur non traitée ou d'un problème de propriété nulle, mais pouvez-vous s'il vous plaît expliquer davantage ou écrire un extrait de code ?

3 votes

Je ne devrais pas avoir à le faire .GetDatabaseValues(); si vous venez de sauvegarder votre modèle dans la base de données. L'ID devrait se repopuler automatiquement dans le modèle.

19voto

Azhar Mansuri Points 264

Vous devez définir la propriété de StoreGeneratedPattern à l'identité et ensuite essayer votre propre code.

Ou bien vous pouvez aussi utiliser ceci.

using (var context = new MyContext())
{
  context.MyEntities.AddObject(myNewObject);
  context.SaveChanges();

  int id = myNewObject.Id; // Your Identity column ID
}

7 votes

Comme la réponse la plus votée.

3 votes

StoreGeneratedPattern était la pièce manquante pour moi.

1 votes

C'est ce qu'il faut faire quand on travaille avec ORACLE et le déclencheur ON-Insert,

18voto

Snowbear Points 10826

L'objet que vous sauvegardez doit avoir un nom correct. Id après avoir propagé les changements dans la base de données.

27 votes

Avez-vous vu l'exception intérieure ? ;-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X