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?
SaveChanges
tout de suite juste pour obtenir l'identifiant. Plus de lecture ici .
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?
SaveChanges
tout de suite juste pour obtenir l'identifiant. Plus de lecture ici .
Réponses:
C'est assez simple. Si vous utilisez des ID générés par la base de données (comme IDENTITY
dans MS SQL), il vous suffit d'ajouter une entité à ObjectSet
et SaveChanges
sur les éléments associés 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
}
Le framework d'entité suit par défaut chacun INSERT
avec SELECT SCOPE_IDENTITY()
quand les Id
s générés automatiquement sont utilisés.
J'avais utilisé la réponse de Ladislav Mrnka pour récupérer avec succès les identifiants lors de l'utilisation de l'Entity Framework, mais je poste ici parce que je l'avais mal utilisé (c'est-à-dire si je ne l'utilisais pas) et pensais publier mes résultats ici dans les gens cherchent à "résoudre" le problème que j'avais.
Considérons un objet Order qui a 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 j'avais à 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 j'enregistre les modifications, l'ID généré pour le client est également ajouté à la commande. Je n'ai pas besoin des étapes supplémentaires
Je suis conscient que cela ne répond pas à la question d'origine, mais j'ai pensé que cela pourrait aider les développeurs qui sont nouveaux dans EF à sur-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 se terminent en une seule transaction, évitant potentiellement les données orphin (soit toutes les mises à jour sont terminées, soit aucune ne le fait).
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. Nous devons donc recharger à nouveau l'entité à partir de la base de données,
db.Entry(MyNewObject).GetDatabaseValues();
alors
int id = myNewObject.Id;
Regardez la réponse de @jayantha dans la question ci-dessous:
La recherche de la réponse @christian dans la question ci-dessous peut également aider:
.GetDatabaseValues();
si vous venez d'enregistrer votre modèle dans la base de données. L'ID doit se repeupler automatiquement sur le modèle.
GetDatabaseValues()
s'il ne connaît pas l'ID de l'objet à rechercher dans la base de données?
Veuillez vous 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 l'identité, puis essayer votre propre code.
Sinon, vous pouvez également l'utiliser.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
StoreGeneratedPattern
était la pièce manquante pour moi.
Vous ne pouvez obtenir l'ID qu'après avoir enregistré, au lieu de cela, vous pouvez créer un nouveau Guid et l'attribuer avant de l'enregistrer.
Je tombe sur une situation où j'ai besoin d'insérer les données dans la base de données et d'exiger simultanément l'ID principal en utilisant le cadre d'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;
}
Toutes les réponses sont très bien adaptées à leurs propres scénarios, ce que j'ai fait différemment, c'est que j'ai attribué l'int PK directement à partir de l'objet (TEntity) que Add () a renvoyé à une variable int comme 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
}
donc au lieu de créer un tout nouvel objet, vous prenez juste ce que vous voulez :)
EDIT Pour M. @GertArnold:
Add
(si c'est le cas DbSet.Add
) n'attribue pas de valeur par magie EmployeeId
.
SaveChanges
. Impossible. À moins que vous n'ayez un autre processus à attribuer EmployeeId
, par exemple dans Employee
le constructeur de. OU vous utilisez le noyau EF ForSqlServerUseSequenceHiLo
. Quoi qu'il en soit, vous ne donnez pas l'image entière.
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Cela fonctionnera.
Repository
. Et "cela fonctionnera" est une explication!.
Il existe deux stratégies:
Utiliser une base de données générée ID
( int
ou GUID
)
Les inconvénients:
Vous devez effectuer SaveChanges()
pour obtenir les ID
entités juste enregistrées.
Avantages:
Peut utiliser l' int
identité.
Utiliser le client généré ID
- GUID uniquement.
Avantages: Minification des SaveChanges
opérations. Capable d'insérer un grand graphique de nouveaux objets par opération.
Les inconvénients:
Autorisé uniquement pour GUID
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())
à l'intérieur des propriétés de la table sous l'en-tête Valeur par défaut ou Liaison, permettant à l'ID d'être rempli lors de son insertion.
Le problème est que si vous créez une table et ajoutez le
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
partie plus tard, les futures bases de données de mise à jour ne rajouteront pas le (newsequentialid ())
Pour corriger la bonne façon, vous devez effacer la migration, supprimer la base de données et re-migrer ... ou vous pouvez simplement ajouter (newsequentialid ()) dans le concepteur de table.
when -column- is NULL, then NEWID()