7

Bir NHibernate Linq sorgusu var, nasıl çalışacağımı bilmiyorum.NHibernate, hatalı birleştirme ile SQL üretiyor

Sorun, bu makaledeki bir sol birleştirilmiş tablodan null bir int sütunu kullanmaktan geliyor gibi görünüyor. Bu, birliğin iç birleştirme gibi davranmasına neden oluyor.

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) 

bu ürettiği SQL benziyor (itibaren katılmak - tüm seçer görmek gerekmez)

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)] 

Yani soruna neden olan bölüm çizgisi 5'tir yukarıdaki pasaj. Gördüğünüz gibi, NHibernate, WorkflowCaseView Görünümümde bir 'eski okul' katılımı yapmaya çalışıyor. Bu, sorgunun, WorkflowAction tablosunda CaseId bulunmayan diğer geçerli eylemleri hariç tutmasına neden olur.

NHibernate'in neden bu SQL'i yazdığını ve daha iyi bir sorgu oluşturmak için nasıl teşvik edebileceğimi açıklayabilir misiniz?

Teşekkürler! Geri başka bir yol gidiyor bir hasMany olmalıdır eğer bu baktığımızda

 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"); 

Önemli bitleri WorkflowCaseViewMap

 Table("Kctc.WorkflowCaseView"); 
     Id(x => x.Id).Column("CaseId"); 
     Map(x => x.MooseUserId).Nullable(); 

den WorkflowActionMap dan

Önemli bitleri, ben ... acaba

DÜZENLE.

cevap

0

Bu birleştirmeyi bir saklı yordam kullanarak gerçekleştirdim. Umarım NHibernate bu hatayı yakında giderir.

3

yardım etmek görünmüyor Bunu için Where maddesinin değiştirilmesine gerek: Eğer koşulsuz erişim çünkü

.Where(x => x.AssignedUser.Id == userId || 
     (x.CaseView != null && x.CaseView.MooseUserId == userId)) 

her zaman CaseView olacağı NHibernate anlatmak geçerli Where maddesi ile onun özellikleri. Bu bilgiye dayanarak NHibernate, left outer join'dan inner join'a ("eski okul" birleştirmesine) yapılan sorguyu en iyi duruma getirir (

+0

Hızlı cevap için teşekkürler. Önerinizi denedim (ve aynı şeyle kendim geldim, sadece .HasValue yerine! = Null) ve yardımcı olmadı. –

+0

@MarkWithers: Bu kısmı "Where" maddesinden tamamen kaldırırsanız ne olur? WorkflowCaseAction ve WorkflowCaseView' arasındaki eşlemeniz nasıl? –

+0

"|| x.CaseView.MooseUserId == userId" ifadesini nerede saklarsa, kayıt kayıtları olmadan geri eylemleri getirir ve beklediğim gibi üç sol dış bağlantı kullanır. –

0

Fluent NHibernate ürününü deneyin. aşağıdaki gibi şeyler doğru topu parkta seni almak gerekir:

var List<WorkflowAction> = FluentSessionManager.GetSession().CreateCriteria<WorkflowAction>() 
     .SetFetchMode("CaseView", FetchMode.Eager) 
     .SetFetchMode("WorkflowActionType", FetchMode.Eager) 
     .SetFetchMode("WorkflowActionPriorityList", FetchMode.Eager) 
     .CreateAlias("AssignedUser", "au") 
     .CreateAlias("CaseView", "cv") 
     .Add(Expression.Or(Expression.Eq("au.Id", userId), Expression.Eq("cv.MooseUserId", userId))) 
     .List<WorkflowAction>(); 

Unutmayın, ben basit bir yardımcı sınıf ile veya bir doğrudan diyebilirsiniz FluentSessionManager.GetSession() uzanan özel bir sınıf var sayfa bazında sayfa. FluentSessionManager kurulumunuz önemli ölçüde farklı olabilir. Ama nihayetinde ".CreateCriteria() ..." kodunuz ve benimki eşleşmeli. "WorkflowAction" varsayımı, sorguya karşı çağrılan tablodur.