Ho alcuni modelli come quelli qui sotto:
public class Mutant
{
public long Id { get; set; }
...
// Relations
public long OriginalCodeId { get; set; }
public virtual OriginalCode OriginalCode { get; set; }
public int DifficultyLevelId { get; set; }
public virtual DifficultyLevel DifficultyLevel { get; set; }
}
e
public class OriginalCode
{
public long Id { get; set; }
...
// Relations
public virtual List<Mutant> Mutants { get; set; }
public virtual List<OriginalCodeInputParameter> OriginalCodeInputParameters { get; set; }
}
e nel OnModelCreating
di DBContext
ho creato relazioni come queste:
modelBuilder.Entity<Mutant>()
.HasOne(m => m.OriginalCode)
.WithMany(oc => oc.Mutants)
.HasForeignKey(m => m.OriginalCodeId)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
modelBuilder.Entity<Mutant>()
.HasOne(m => m.DifficultyLevel)
.WithMany(dl => dl.Mutants)
.HasForeignKey(m => m.DifficultyLevelId)
.OnDelete(Microsoft.EntityFrameworkCore.Metadata.DeleteBehavior.Restrict);
ora quando chiedo mutanti, il codice originale è nullo:
ma non appena richiedo i OriginalCode
come di seguito:
quindi il campo OriginalCode
dei mutanti non sarà nullo:
Qual è il motivo e come posso ripararlo?
Il motivo è spiegato nella sezione Caricamento dei dati correlati della documentazione di EF Core.
Il primo comportamento è dato dal fatto che EF Core attualmente non supporta il caricamento lazy, quindi normalmente otterrete il valore null
per le proprietà di navigazione fino a quando non li caricate specificamente tramite caricamento desideroso o esplicito. Tuttavia, la sezione di caricamento Eager contiene quanto segue:
Mancia
Entity Framework Core aggiusterà automaticamente le proprietà di navigazione su qualsiasi altra entità precedentemente caricata nell'istanza di contesto. Pertanto, anche se non includi esplicitamente i dati per una proprietà di navigazione, la proprietà potrebbe ancora essere popolata se alcune o tutte le entità correlate fossero state precedentemente caricate.
che spiega perché la proprietà di navigazione non è nulla nel secondo caso.
Ora, non sono sicuro di quale dei due comportamenti desideri correggere, quindi proverò ad affrontarli entrambi.
Il primo comportamento può essere "risolto" utilizzando uno dei metodi attualmente disponibili per il caricamento dei dati correlati, ad esempio il caricamento ansioso:
var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();
Il secondo comportamento è "in base alla progettazione" e non può essere controllato. Se vuoi evitarlo, assicurati di utilizzare una nuova nuova istanza di DbContext
solo per eseguire una singola query per ritentare i dati necessari.
Aggiornamento: a partire dalla versione 2.1, EF Core supporta il caricamento lento . Tuttavia non è abilitato per impostazione predefinita, quindi per utilizzarlo è necessario contrassegnare tutte le proprietà di navigazione virtual
, installare Microsoft.EntityFrameworkCore.Proxies e abilitarlo tramite la chiamata UseLazyLoadingProxies
o utilizzare il caricamento Lazy senza proxy , entrambi illustrati con esempi nell'EF Core documentazione.