Ho una query Linq di NHibernate che non funziona come mi aspetterei.NHibernate sta producendo SQL con un cattivo join
Il problema sembra derivare dall'utilizzo di una colonna int Nullabile da una tabella unita sinistra nella clausola where. Questo fa sì che il join si comporti come un join interno.
var list = this.WorkflowDiaryManager.WorkflowActionRepository.All
.Fetch(x => x.CaseView)
.Fetch(x => x.WorkflowActionType)
.ThenFetchMany(x => x.WorkflowActionPriorityList)
.Where(x => x.AssignedUser.Id == userId || x.CaseView.MooseUserId == userId)
Lo SQL prodotta da questo appare come (dal punto di giunzione in poi - non è necessario per vedere tutte le seleziona)
from Kctc.WorkflowAction workflowac0_
left outer join Kctc.WorkflowCaseView workflowca1_ on workflowac0_.CaseId=workflowca1_.CaseId
left outer join Kctc.WorkflowActionType workflowac2_ on workflowac0_.WorkflowActionTypeId=workflowac2_.WorkflowActionTypeId
left outer join Kctc.WorkflowActionPriority workflowac3_ on workflowac2_.WorkflowActionTypeId=workflowac3_.WorkflowActionTypeId
,Kctc.WorkflowCaseView workflowca4_
where workflowac0_.CaseId=workflowca4_.CaseId
and ([email protected] or workflowca4_.[MooseUserId][email protected]);
@p0 = 1087 [Type: Int32 (0)],
@p1 = 1087 [Type: Int32 (0)]
Così la parte che causa il problema è la linea 5 della il frammento sopra. Come puoi vedere, NHibernate sta provando a fare un join "old-school" sulla mia vista WorkflowCaseView. Questo fa sì che la query escluda azioni altrimenti valide che non hanno un CaseId nella tabella WorkflowAction.
Qualcuno potrebbe spiegare perché NHibernate stia scrivendo questo SQL e come potrei incoraggiarlo a produrre una query migliore?
Grazie!
bit importante dal WorkflowActionMap
bit Table("Kctc.WorkflowAction");
Id(x => x.Id).GeneratedBy.Identity().Column("WorkflowActionId");
References(x => x.WorkflowActionType).Column("WorkflowActionTypeId").Unique();
References(x => x.CompletedBy).Column("CompletedBy");
References(x => x.CaseView).Column("CaseId").Not.Update().Unique();
References(x => x.AssignedUser).Column("AssignedUser");
importante dal WorkflowCaseViewMap
Table("Kctc.WorkflowCaseView");
Id(x => x.Id).Column("CaseId");
Map(x => x.MooseUserId).Nullable();
Guardando a questo, mi chiedo se dovrei avere una hasMany tornare dall'altra parte ...
MODIFICARE. Non sembra aiutare
Grazie per la risposta rapida. Ho provato il tuo suggerimento (e mi è venuta in mente la stessa cosa, usando solo .HasValue invece di! = Null) e non ha aiutato. –
@MarkWithers: cosa succede se si rimuove completamente tale parte dalla clausola 'Where'? Com'è la tua mappatura tra 'WorkflowCaseAction' e' WorkflowCaseView'? –
Se rimuovo "|| x.CaseView.MooseUserId == userId" dalla clausola where, riporta le azioni senza record del caso e utilizza tre join esterni a sinistra come mi aspetterei. –