Perché l’esterno sinistro si unisce?

strano. (Probabilmente non è strano, per niente)

Ho 3 oggetti, Employee, Rota e Department.

public class Employee { public int Id { get; set; } public String Name { get; set; } public virtual Department Department { get; set; } } internal class EmployeeMapping : EntityTypeConfiguration { public EmployeeMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("UserId"); HasRequired(a => a.Department).WithOptional().Map(a => a.MapKey("DepartmentId")); } } public class Department { public int Id { get; set; } public String Name { get; set; } } internal class DepartmentMapping : EntityTypeConfiguration { public DepartmentMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("DepartmentId"); } } public class Rota { public int Id { get; set; } public virtual Employee Employee { get; set; } public virtual Department Department { get; set; } } internal class RotaMapping : EntityTypeConfiguration { public RotaMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("RotaId"); HasOptional(a => a.Employee).WithOptionalDependent().Map(a => a.MapKey("EmployeeId")); HasOptional(a => a.Department).WithOptionalDependent().Map(a => a.MapKey("DepartmentId")); } } 

Non è complicato, davvero. Rota può avere un Dipendente e / o un Dipartimento ad esso assegnato, tutto questo è configurato usando Fluent. Tutte le mie associazioni sono corrette (lo schema è perfetto), tuttavia ho strane stranezze.

Quando myContext.Departments.FirstOrDefault() un myContext.Departments.FirstOrDefault() e myContext.Departments.FirstOrDefault() uno sguardo all’SQL generato, esiste un JOINT OUTER SINISTRO su Employee & Rota. Perché questo è lì?
Non voglio farlo. Forse i miei mapping Fluent non sono corretti? Ho provato tutti i tipi, ma non riesco a capirlo. Lo capirei se voglio un object Rota, che si unisca al Dipartimento. Ma non il contrario!

Se faccio myContext.Departments.AsNoTracking().FirstOrDefault() non esegue LEFT OUTER JOIN .

Qualche idea ragazzi?

Saluti, D

Il motivo è mapping errata. Sembra corretto ma non lo è. Usa questi invece:

 internal class EmployeeMapping : EntityTypeConfiguration { public EmployeeMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("UserId"); HasRequired(a => a.Department).WithMany() .Map(a => a.MapKey("DepartmentId")); } } internal class RotaMapping : EntityTypeConfiguration { public RotaMapping() { HasKey(a => a.Id); Property(a => a.Id).HasColumnName("RotaId"); HasOptional(a => a.Employee).WithMany() .Map(a => a.MapKey("EmployeeId")); HasOptional(a => a.Department).WithMany() .Map(a => a.MapKey("DepartmentId")); } } 

La tua mapping viene interpretata correttamente quando la creazione di database e database sembra corretta, ma EF pensa di mappare tutte le relazioni come uno a uno. Questo confonde EF e genererà query usate per uno a uno per creare riferimenti di entity framework interne. Questi join di sinistra sono necessari per la relazione uno a uno quando dici a EF che le entity framework dipendenti sono facoltative – EF non sa se esistono a meno che non carichi le loro chiavi.

Non sono affatto un esperto e sto solo indovinando qui. Ma potresti provare la query nel modo in cui l’entity framework lo sta facendo e poi provare come preferisci vedere la query e pubblicare i differenziali di tempo. Forse la struttura dell’ quadro è su qualcosa qui, ma ne dubito.

Ho una teoria. L’unione esterna sinistra scompare quando si distriggers il rilevamento delle modifiche. Anche Dipendente e Rota hanno riferimenti al Dipartimento.

Quindi la mia teoria è che con il tracciamento delle modifiche su Entity Framework si tenta di caricare tutte le entity framework con un riferimento al dipartimento nel caso in cui debba effettuare un aggiornamento a cascata al reparto.

In altre parole, pensa che una modifica a un dipartimento potrebbe causare una modifica all’Impiegato o al Rota che fa riferimento al dipartimento, quindi carica tutto nel caso.