Mam kwerendę NHibernate Linq, która nie działa tak, jak bym się spodziewał.NHibernate tworzy kod SQL ze złym złączem
Problem wydaje się wynikać z użycia kolumny z zerową wartością int z lewej złączonej tabeli w klauzuli where. To powoduje, że sprzężenie zachowuje się jak wewnętrzne sprzężenie.
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)
SQL produkowane przez to wygląda (od przyłączyć roku - nie ma potrzeby, aby zobaczyć wszystkie wybiera)
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)]
więc część, która jest przyczyną problemu jest linia 5 powyższy fragment. Jak widać, NHibernate próbuje dołączyć do "starej szkoły" w moim widoku WorkflowCaseView. Powoduje to, że zapytanie wyklucza inne ważne akcje, które nie mają identyfikatora CaseId w tabeli WorkAllAction.
Czy ktoś mógłby wyjaśnić, dlaczego NHibernate pisze ten SQL i jak mogę go zachęcić do stworzenia lepszego zapytania?
Dzięki!
Ważne bity od WorkflowActionMap
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");
Ważne bity od WorkflowCaseViewMap
Table("Kctc.WorkflowCaseView");
Id(x => x.Id).Column("CaseId");
Map(x => x.MooseUserId).Nullable();
Patrząc na to, zastanawiam się, czy powinienem mieć hasMany wraca inną drogą ...
EDYTOWAĆ. Nie wydaje się, aby pomóc
Dzięki za szybką odpowiedź. Próbowałem twojej sugestii (i wymyśliłem to samo, używając tylko .HasValue zamiast! = Null) i to nie pomogło. –
@MarkWithers: Co się stanie, jeśli całkowicie usuniesz tę część z klauzuli "Where"? W jaki sposób mapujesz między 'WorkflowCaseAction' i' WorkflowCaseView'? –
Po usunięciu "|| x.CaseView.MooseUserId == userId" z klauzuli where wywołuje akcje bez rekordów sprawy i używa trzech lewych złączeń zewnętrznych, tak jak oczekiwałbym. –