Ich habe ein Problem mit Entity Framework in Asp.net. Ich möchte den ID-Wert erhalten, wenn ich der Datenbank ein Objekt hinzufüge. Wie kann ich das machen?
SaveChanges
sofort anrufen , um die ID zu erhalten. Lesen Sie hier weiter .
Ich habe ein Problem mit Entity Framework in Asp.net. Ich möchte den ID-Wert erhalten, wenn ich der Datenbank ein Objekt hinzufüge. Wie kann ich das machen?
SaveChanges
sofort anrufen , um die ID zu erhalten. Lesen Sie hier weiter .
Antworten:
Es ist ziemlich einfach. Wenn Sie DB-generierte IDs verwenden (wie IDENTITY
in MS SQL), müssen Sie nur Entitäten zu ObjectSet
und SaveChanges
auf verwandten hinzufügen ObjectContext
. Id
wird automatisch für Sie ausgefüllt:
using (var context = new MyContext())
{
context.MyEntities.Add(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it's here
}
Das Entity Framework folgt standardmäßig jeweils INSERT
mit SELECT SCOPE_IDENTITY()
automatisch generierten Id
s.
Ich habe die Antwort von Ladislav Mrnka verwendet, um bei Verwendung des Entity Frameworks erfolgreich IDs abzurufen. Ich poste jedoch hier, weil ich es nicht verwendet habe (dh dort verwendet habe, wo es nicht erforderlich war), und dachte, ich würde meine Ergebnisse hier veröffentlichen Fall Leute versuchen, das Problem, das ich hatte, zu "lösen".
Stellen Sie sich ein Bestellobjekt vor, das eine Fremdschlüsselbeziehung zum Kunden hat. Als ich gleichzeitig einen neuen Kunden und eine neue Bestellung hinzufügte, tat ich so etwas.
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
In meinem Fall war dies jedoch nicht erforderlich, da ich eine Fremdschlüsselbeziehung zwischen customer.Id und order.CustomerId hatte
Alles was ich tun musste war das;
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
Wenn ich jetzt die Änderungen speichere, wird die für den Kunden generierte ID ebenfalls zur Bestellung hinzugefügt. Ich brauche keine zusätzlichen Schritte
Ich bin mir bewusst, dass dies die ursprüngliche Frage nicht beantwortet, dachte aber, dass es Entwicklern, die EF noch nicht kennen, helfen könnte, die am häufigsten gewählte Antwort für etwas zu verwenden, das möglicherweise nicht erforderlich ist.
Dies bedeutet auch, dass Aktualisierungen in einer einzigen Transaktion abgeschlossen werden, wodurch möglicherweise Waisen-Daten vermieden werden (entweder alle Aktualisierungen sind abgeschlossen oder keine).
Sie müssen die Entität nach dem Speichern der Änderungen neu laden. Weil es durch einen Datenbank-Trigger geändert wurde, der von EF nicht verfolgt werden kann. Also müssen wir die Entität erneut aus der Datenbank laden.
db.Entry(MyNewObject).GetDatabaseValues();
Dann
int id = myNewObject.Id;
Schauen Sie sich die Antwort von @jayantha in der folgenden Frage an:
Die Antwort von @christian in der folgenden Frage kann ebenfalls hilfreich sein:
.GetDatabaseValues();
wenn Sie Ihr Modell gerade in der Datenbank gespeichert haben. Die ID sollte automatisch in das Modell übernommen werden.
GetDatabaseValues()
wenn es die ID des zu suchenden Objekts in der Datenbank nicht kennt?
Bitte beziehen Sie sich auf diesen Link.
http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/
Sie müssen die Eigenschaft von StoreGeneratedPattern auf Identität setzen und dann Ihren eigenen Code ausprobieren.
Oder Sie können dies auch verwenden.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
StoreGeneratedPattern
war das fehlende Stück für mich.
Sie können die ID erst nach dem Speichern erhalten. Stattdessen können Sie eine neue Guid erstellen und vor dem Speichern zuweisen.
Ich stoße auf eine Situation, in der ich die Daten in die Datenbank einfügen und gleichzeitig die primäre ID mithilfe des Entity Frameworks benötigen muss. Lösung:
long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
{
InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
InfoBase.Add(generalinfo);
InfoBase.Context.SaveChanges();
id = entityclassobj.ID;
return id;
}
Alle Antworten sind sehr gut für ihre eigenen Szenarien geeignet. Was ich anders gemacht habe, ist, dass ich die int PK direkt vom Objekt (TEntity) zugewiesen habe, das Add () an eine int-Variable wie diese zurückgegeben hat.
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
}
Anstatt ein ganz neues Objekt zu erstellen, nimmst du einfach, was du willst :)
BEARBEITEN Für Herrn @GertArnold:
Add
(wenn dies der DbSet.Add
Fall ist ) kein magischer Wert zugewiesen wird EmployeeId
.
SaveChanges
. Unmöglich. Es sei denn, Sie haben einen anderen Prozess, der zugewiesen wird EmployeeId
, z. B. im Employee
Konstruktor. ODER Sie verwenden EF Core ForSqlServerUseSequenceHiLo
. Wie auch immer, Sie geben nicht das ganze Bild.
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Das wird funktionieren.
Repository
ist. Und "das wird funktionieren" ist eine Erklärung!.
Es gibt zwei Strategien:
Verwenden Sie die von der Datenbank generierte ID
( int
oder GUID
)
Nachteile:
Sie sollten ausführen SaveChanges()
, um die ID
gerade gespeicherten Entitäten abzurufen.
Vorteile:
Kann int
Identität verwenden.
Client generiert verwenden ID
- nur GUID.
Vorteile: Minimierung der SaveChanges
Operationen. Kann pro Operation einen großen Graphen neuer Objekte einfügen.
Nachteile:
Nur erlaubt für GUID
Wenn Sie zuerst EF 6.x-Code verwenden
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
und initialisieren Sie eine Datenbanktabelle, es wird ein setzen
(newsequentialid())
innerhalb der Tabelleneigenschaften unter der Überschrift Standardwert oder Bindung, sodass die ID beim Einfügen ausgefüllt werden kann.
Das Problem ist, wenn Sie eine Tabelle erstellen und die hinzufügen
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Teil später werden zukünftige Update-Datenbanken die (newsequentialid ()) nicht mehr hinzufügen.
Um den richtigen Weg zu finden, müssen Sie die Migration löschen, die Datenbank löschen und erneut migrieren ... oder Sie können einfach (newsequentialid ()) zum Tabellen-Designer hinzufügen.
when -column- is NULL, then NEWID()