Sto cercando di capire come eseguire senza problemi un aggiornamento parziale (fondamentalmente un HTTP PATCH
) di un'entità, utilizzando Entity Framework 6.0, ma sono perplesso rispetto al numero di esempi disponibili che non sembra funzionare per me (anche quelli che non sono ovviamente per un'altra versione di EF).Aggiornamento parziale di un'entità in EF6
Quello che mi piacerebbe da compiere:
- L'entità viene aggiornato senza dover caricare in primo luogo; cioè c'è un solo viaggio al database solo
- le proprietà che ho touch sono aggiornati - gli altri sono lasciati come è
Il più vicino che ho ottenuto è ben descritto da this answer ad una domanda molto simile, e illustrato dal codice seguente:
public async Task UpdateMyEntity(int id, int? updatedProperty, string otherProperty)
{
using (var context = new MyDbContext())
{
var entity = new MyEntity { Id = id };
context.MyEntities.Attach(entity);
if (updatedProperty != null) { entity.Property = updatedProperty.Value; }
if (!string.IsNullOrEmpty(otherProperty) { entity.OtherProperty = otherProperty; }
await context.SaveChangesAsync();
}
}
Ora, questo funziona per le entità semplici, ma sto ottenendo gli errori di convalida entità perché ho un paio di proprietà e relazioni richieste che non sono aggiornate e quindi non presente nel soggetto annesso . Come notato, vorrei semplicemente ignorare quelli.
ho il debug e verificato che context.Entry(entity).Property(e => e.Property).IsModified
modifiche a true
quando quella linea viene eseguito, e che tutte le proprietà che non ho mai toccare ancora tornare false
per i controlli simili, così ho pensato EF sarebbe in grado di gestire questa situazione.
È possibile risolvere questo problema con i due vincoli sopra riportati? Come?
Aggiornamento:
Con s' answerLSU.Net Capisco un po' quello che devo fare, ma non funziona completamente. La logica fallisce per le proprietà referenziali.
Si consideri il seguente modello di dominio:
public class MyEntity
{
public int Id { get; set; }
public int Property { get; set; }
[Required]
public string OtherProperty { get; set; }
[Required]
public OtherEntity Related { get; set; }
}
public class OtherEntity
{
public int Id { get; set; }
public string SomeProperty { get; set; }
}
Ora, se cerco di aggiornare un MyEntity
, faccio la seguente:
var entity = new MyEntity { Id = 123 }; // an entity with this id exists in db
context.MyEntities.Attach(entity);
if (updatedProperty != null) { entity.Property = updatedProperty.Value; }
await context.SaveChangesAsync();
Nel mio metodo di convalida personalizzato, ignorato come in the answer below, l'errore di convalida sulla proprietà richiesta OtherProperty
viene rimosso correttamente, poiché non viene modificato. Tuttavia, ottengo ancora un errore di convalida sulla proprietà Related
, perché entityEntry.Member("Related") is DbReferenceEntry
, non DbPropertyEntry
, e quindi l'errore di convalida non è contrassegnato come falso errore.
Ho provato ad aggiungere una clausola separata, analoga per la gestione delle proprietà di riferimento, ma lo entityEntry
non sembra contrassegnare quelli modificati; con relation = member as DbReferenceEntry
, relation
non ha nulla per indicare che la relazione è cambiata.
In questo caso è possibile verificare la presenza di errori falsi? Ci sono altri casi che devo gestire specialmente (relazioni uno-a-molti, per esempio)?
Questo è ottimo, ma non riesce ancora a rimuovere gli errori di convalida per proprietà referenziali non toccate. Aggiornerò l'OP per mostrare un caso d'uso. –
Si prega di consultare il mio aggiornamento :) Altre idee sono i benvenuti! –