web-dev-qa-db-fra.com

Comment puis-je obtenir l'ID d'une entité insérée dans la structure Entity?

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

530
ahmet

C'est assez facile. Si vous utilisez des ID générés par une base de données (comme IDENTITYdans MS SQL), il vous suffit d'ajouter une entité à ObjectSetet SaveChangessur ObjectContextname__. Idsera automatiquement rempli pour vous:

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

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

Le cadre d'entité suit par défaut chaque INSERTavec SELECT SCOPE_IDENTITY() lorsque le Idname__s généré automatiquement est utilisé.

887
Ladislav Mrnka

J'avais utilisé réponse de Ladislav Mrnka pour récupérer des identifiants lors de l'utilisation d'Entity Framework. Cependant, je poste ici parce que je l'avais mal utilisé (c'est-à-dire que je ne l'avais pas utilisé) et je pensais posterait mes découvertes ici au cas où des personnes chercheraient à "résoudre" le problème que j'avais.

Considérons un objet Order ayant une relation de clé étrangère avec le client. Quand j'ai ajouté un nouveau client et une nouvelle commande en même temps, je faisais quelque chose comme ça;

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 je devais faire était ceci;

var customer = new Customer(); //no Id yet;
var order = new Order{Customer = customer}; 
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 des étapes supplémentaires

Je suis conscient du fait que cela ne répond pas à la question initiale, mais que cela pourrait aider les développeurs qui débutent avec EF à utiliser de manière excessive la réponse la plus votée pour quelque chose d'inutile.

95
mark_h

Vous devez recharger l'entité après avoir enregistré les modifications. Parce qu'il a été modifié par un déclencheur de base de données qui ne peut pas être suivi par EF. SO nous devons recharger à nouveau l'entité à partir de la base de données,

db.Entry(MyNewObject).GetDatabaseValues();

Ensuite

int id = myNewObject.Id;

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

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

Rechercher la réponse de @christian ci-dessous peut également aider:

contexte de rafraîchissement Entity Framework?

27
QMaster

S'il vous plaît se référer ce lien.

http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/

Vous devez définir la propriété de StoreGeneratedPattern sur identité, puis essayer votre propre code.

Sinon, vous pouvez aussi l'utiliser.

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

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

L'objet que vous enregistrez doit avoir un Id correct après la propagation des modifications dans la base de données.

12
Snowbear
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;

Cela fonctionnera.

5
Saket Choubey

Vous pouvez obtenir un identifiant uniquement après la sauvegarde. Vous pouvez plutôt créer un nouveau Guid et l'attribuer avant de le sauvegarder.

Je tombe dans une situation où j'ai besoin d'insérer les données dans la base de données et d'avoir simultanément besoin de l'identifiant principal à l'aide du cadre de l'entité. Solution :

long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
 {
    InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
    InfoBase.Add(generalinfo);
    InfoBase.Context.SaveChanges();
    id = entityclassobj.ID;
    return id;
 }
4
Mr Kunal

Toutes les réponses conviennent très bien à leurs propres scénarios. Ce que j’ai fait de différent, c’est que j’ai assigné la PK int directement à partir d’objet (TEntity) que Add () a renvoyé à une variable int telle que celle-ci;

using (Entities entities = new Entities())
{
      int employeeId = entities.Employee.Add(new Employee
                        {
                            EmployeeName = employeeComplexModel.EmployeeName,
                            EmployeeCreatedDate = DateTime.Now,
                            EmployeeUpdatedDate = DateTime.Now,
                            EmployeeStatus = true
                        }).EmployeeId;

      //...use id for other work
}

alors au lieu de créer un nouvel objet entier, il vous suffit de prendre ce que vous voulez :)

EDIT Pour M. @GertArnold:

enter image description here

2
IteratioN7T

Il y a deux stratégies:

  1. Utilisez ID(intou GUIDgénéré par la base de données)

    Les inconvénients:

    Vous devez exécuter SaveChanges() pour obtenir le IDpour les entités simplement enregistrées.

    Avantages:

    Peut utiliser l'identité intname__.

  2. Utilisez le nom ID__ GUID généré par le client uniquement.

    Avantages: Minification des opérations SaveChangesname__. Capable d'insérer un grand graphique de nouveaux objets par une opération.

    Les inconvénients:

    Autorisé uniquement pour GUIDname__

2
Vladislav Furdak

Lorsque vous utilisez d'abord le code EF 6.x

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }

et initialiser une table de base de données, il mettra un

(newsequentialid())

dans les propriétés de la table sous l’en-tête Valeur par défaut ou Liaison, ce qui permet de renseigner l’ID à mesure qu’il est inséré.

Le problème est que si vous créez une table et ajoutez le

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

une partie plus tard, les futures bases de données de mise à jour ne rajouteront pas le (newsequentialid ())

Pour corriger le problème, vous devez effacer la migration, supprimer la base de données et effectuer une nouvelle migration ... ou vous pouvez simplement ajouter (newsequentialid ()) dans le concepteur de table.

1
Jeff Li