So che puoi fare qualcosa come var myObj = _db.MyTable.FirstOrDefault(x=>x.Id==id)
e quindi aggiornare la proprietà myObj
per proprietà che vuoi aggiornare, ma c'è un modo migliore per aggiornare dire 6 di 10 proprietà di myObj
e lasciate le altre 4 da sole o le contrassegnate come un modo in cui sono impostate una sola volta e non sono aggiornabili da ef core?
public class MyObject
{
public string Id { get; set; }
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public string Prop4 { get; set; }
public string Prop5 { get; set; }
public string Prop6 { get; set; }
public string Prop7 { get; set; }
public string Prop8 { get; set; }
public string Prop9 { get; set; }
}
public void UpdateObj(MyObject ojToUpdate)
{
//Is there a better way to write this function if you only want to update a set amount of properties
var myObj = _db.MyObject.First(x=>x.Id==ojToUpdate.Id);
myObj.Prop1 = objToUpdate.Prop1;
myObj.Prop2 = objToUpdate.Prop2;
myObj.Prop3 = objToUpdate.Prop3;
myObj.Prop4 = objToUpdate.Prop4;
myObj.Prop5 = objToUpdate.Prop5;
myObj.Prop6 = objToUpdate.Prop6;
_db.SaveChanges();
}
Ovviamente puoi scrivere qualcosa come _db.MyObject.Update(objToUpdate)
. Il problema con questa affermazione è che l'utente può aggiornare il prop 4/5/6 che non voglio che aggiorni. Sì, lo so che puoi scrivere _db.Entry(myObj).CurrentValues.SetValues(objToUpdate)
e poi chiamare save save ma che supererà le proprietà che voglio essere generato una volta e mai modificato di nuovo.
Grazie in anticipo.
A partire da EF Core 2.0, è possibile utilizzare la proprietà IProperty.AfterSaveBehavior
:
Ottiene un valore che indica se questa proprietà può essere modificata o meno dopo il salvataggio dell'entità nel database.
Se Lancia , verrà generata un'eccezione se un nuovo valore viene assegnato a questa proprietà dopo che l'entità esiste nel database.
Se Ignora , qualsiasi modifica al valore della proprietà di un'entità già esistente nel database verrà ignorata.
Ciò di cui hai bisogno è l'opzione Ignore
. Al momento della stesura di questo documento non esiste un metodo API dedicato dedicato, ma l' impostazione di un valore esplicito durante l'aggiornamento contiene un esempio di come farlo.
Prendendo il tuo esempio, qualcosa del genere:
modelBuilder.Entity<MyObject>(builder =>
{
builder.Property(e => e.Prop7).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Property(e => e.Prop8).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
builder.Property(e => e.Prop9).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;
});
Adesso entrambi
public void UpdateObj(MyObject objToUpdate)
{
var myObj = _db.MyObject.First(x => x.Id == objToUpdate.Id);
_db.Entry(myObj).CurrentValues.SetValues(myObjToUpdate);
_db.SaveChanges();
}
e
public void UpdateObj(MyObject objToUpdate)
{
_db.Update(myObjToUpdate);
_db.SaveChanges();
}
ignorerà i Prop7
, Prop8
e Prop9
del myObjToUpdate
passato.
Aggiornamento (EF Core 3.0+) La suddetta proprietà è stata sostituita con i metodi di estensione GetAfterSaveBehavior e SetAfterSaveBehavior .
Se hai un'entità:
public class Person
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
E tu corri:
var p = ctx.Person.First();
p.Name = "name updated";
ctx.SaveChanges();
EF genererà la seguente istruzione SQL:
È possibile verificarlo utilizzando SQL Server Profiler , lo stesso è vero se si aggiornano le proprietà 6/10.