Ho un problema con Entity Framework in Asp.net. Voglio ottenere il valore ID ogni volta che aggiungo un oggetto al database. Come posso fare questo?
SaveChanges
subito solo per ottenere l'ID. Ulteriori letture qui .
Ho un problema con Entity Framework in Asp.net. Voglio ottenere il valore ID ogni volta che aggiungo un oggetto al database. Come posso fare questo?
SaveChanges
subito solo per ottenere l'ID. Ulteriori letture qui .
Risposte:
È abbastanza facile Se si utilizza DB generato Ids (come IDENTITY
in MS SQL) basta aggiungere entità ObjectSet
e SaveChanges
sulle relative ObjectContext
. Id
verrà riempito automaticamente per te:
using (var context = new MyContext())
{
context.MyEntities.Add(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Yes it's here
}
Il framework delle entità per impostazione predefinita segue ciascuna INSERT
di esse SELECT SCOPE_IDENTITY()
quando Id
vengono utilizzati i messaggi automatici generati .
Stavo usando la risposta di Ladislav Mrnka per recuperare con successo gli Id quando usavo l'Entity Framework, ma sto postando qui perché non lo avevo usato (cioè usandolo dove non era richiesto) e pensavo che avrei pubblicato i miei risultati qui in le persone stanno cercando di "risolvere" il problema che ho avuto.
Si consideri un oggetto Ordine che ha una relazione di chiave esterna con il Cliente. Quando ho aggiunto un nuovo cliente e un nuovo ordine contemporaneamente, stavo facendo qualcosa del genere;
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
Tuttavia, nel mio caso, ciò non era necessario perché avevo una relazione di chiave esterna tra customer.Id e order.CustomerId
Tutto quello che dovevo fare era questo;
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
Ora, quando salvo le modifiche, viene aggiunto all'ordine anche l'ID generato per il cliente. Non ho bisogno di ulteriori passaggi
Sono consapevole che questo non risponde alla domanda originale, ma ho pensato che potesse aiutare gli sviluppatori che non conoscono EF a utilizzare in modo eccessivo la risposta più votata per qualcosa che potrebbe non essere necessario.
Ciò significa anche che gli aggiornamenti vengono completati in un'unica transazione, evitando potenzialmente i dati orphin (tutti gli aggiornamenti sono completi o nessuno lo fa).
È necessario ricaricare l'entità dopo aver salvato le modifiche. Perché è stato modificato da un trigger di database che non può essere monitorato da EF. Quindi dobbiamo ricaricare nuovamente l'entità dal DB,
db.Entry(MyNewObject).GetDatabaseValues();
Poi
int id = myNewObject.Id;
Guarda la risposta di @jayantha nella seguente domanda:
Come posso ottenere l'ID dell'entità inserita nel framework Entity quando utilizzo defaultValue?
Anche la risposta di @christian nella seguente domanda può aiutare:
.GetDatabaseValues();
se hai appena salvato il tuo modello nel DB. L'ID dovrebbe ripopolare automaticamente nel modello.
GetDatabaseValues()
se non conoscesse l'ID dell'oggetto da cercare nel database?
Si prega di fare riferimento a questo link.
http://www.ladislavmrnka.com/2011/03/the-bug-in-storegeneratedpattern-fixed-in-vs-2010-sp1/
Devi impostare la proprietà di StoreGeneratedPattern su identity e quindi provare il tuo codice.
Oppure puoi anche usare questo.
using (var context = new MyContext())
{
context.MyEntities.AddObject(myNewObject);
context.SaveChanges();
int id = myNewObject.Id; // Your Identity column ID
}
StoreGeneratedPattern
era il pezzo mancante per me.
Puoi ottenere l'ID solo dopo il salvataggio, invece puoi creare un nuovo Guid e assegnarlo prima di salvare.
Mi imbatto in una situazione in cui ho bisogno di inserire i dati nel database e contemporaneamente richiedere l'id primario utilizzando il framework di entità. Soluzione:
long id;
IGenericQueryRepository<myentityclass, Entityname> InfoBase = null;
try
{
InfoBase = new GenericQueryRepository<myentityclass, Entityname>();
InfoBase.Add(generalinfo);
InfoBase.Context.SaveChanges();
id = entityclassobj.ID;
return id;
}
Tutte le risposte sono molto adatte ai propri scenari, ciò che ho fatto diversamente è che ho assegnato int PK direttamente dall'oggetto (TEntity) che Add () ha restituito a una variabile int come questa;
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
}
quindi invece di creare un intero nuovo oggetto, prendi semplicemente quello che vuoi :)
MODIFICA Per Mr. @GertArnold:
Add
(se questo è DbSet.Add
) non non è magicamente assegnare un valore a EmployeeId
.
SaveChanges
. Impossibile. A meno che tu non abbia qualche altro processo che assegni EmployeeId
, ad esempio nel Employee
costruttore di. O sei nel core EF utilizzando ForSqlServerUseSequenceHiLo
. Comunque, non stai dando l'intera immagine.
Repository.addorupdate(entity, entity.id);
Repository.savechanges();
Var id = entity.id;
Questo funzionerà.
Repository
sia. E "questo funzionerà" è una spiegazione !.
Esistono due strategie:
Usa generato dal database ID
( int
o GUID
)
Contro:
Dovresti esibirti SaveChanges()
per ottenere le ID
entità appena salvate.
Professionisti:
Può usare l' int
identità.
Usa client generato ID
- Solo GUID.
Pro: minimizzazione delle SaveChanges
operazioni. In grado di inserire un grande grafico di nuovi oggetti per un'operazione.
Contro:
Consentito solo per GUID
Quando si utilizza prima il codice EF 6.x.
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
e inizializzare una tabella di database, metterà a
(newsequentialid())
all'interno delle proprietà della tabella sotto l'intestazione Valore predefinito o Binding, consentendo all'ID di essere popolato al momento dell'inserimento.
Il problema è se si crea una tabella e si aggiunge
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
parte in seguito, i futuri database di aggiornamento non aggiungeranno nuovamente (newsequentialid ())
Correggere il modo corretto è cancellare la migrazione, eliminare il database e ripetere la migrazione ... oppure puoi semplicemente aggiungere (newsequentialid ()) nel designer della tabella.
when -column- is NULL, then NEWID()