簡體   English   中英

QueryOver集合包含所有值

[英]QueryOver collection contains all values

簡化域名:

public class MasterDocument {
    Guid ID;
    Program StorageCompartment;
    ISet<DocumentCompartment> Compartments;
}
public class Program {
    int ID;
    string GroupName;
}
public class DocumentCompartment {
    int ID;
    Program AssociatedCompartment;
    MasterDocument AssociatedDocument;
}
public class Document {
    Guid ID;
    MasterDocument MasterDocument;
    //Many more properties
}

我知道這有點令人費解,但由於我們通過將某些記錄(如文檔)放入與其所屬的Program / Compartment(可互換術語)相對應的不同DB中而處理的安全性問題,因此模式存在。 MasterDocument,Program和DocumentCompartment的表位於“主”數據庫中,該數據庫包含所有隔離專區的信息,而幾個不同的數據庫將各自包含自己的Documents表。 無論如何,關於問題:

我正在嘗試構建一個查詢,通過這個查詢傳遞一個組名列表,我只想要那些沒有關聯區域的文檔,這些文檔沒有包含在該組名列表中。

舉個例子:
Doc1與隔室P1相關聯
Doc2與P2,P3和P7相關聯
Doc3與P1和P3相關聯
我想檢查組:P1,P3,P4,P7(這些是我允許的組)

我應該回到Doc1和Doc3,因為我沒有P2的權限,而Doc2需要這樣做。 我能夠使用LINQ提供程序使用以下查詢執行此操作:

string[] groups = new[] { "P1", "P3", "P4", "P7" };
return Session.Query<Document>().Where(doc => doc.MasterDocument.Compartments.All(comp => groups.Contains(comp.AssociatedCompartment.GroupName));

(還有一個關於上面的注釋:如果我嘗試將該邏輯封裝在Document類中並將該方法傳遞給'Where'方法,例如返回Session.Query()。Where(doc => doc.CanAccess(groups)) ,然后我得到一個System.NotSupportedException。我有點理解為什么,但如果有一個解決方法,這將是很好的。)

生成的SQL生成如下所示:

exec sp_executesql 
N'select
doc.DocumentGuid as guid
from Documents doc 
where  not (exists 
(select comp.DocumentCompartmentID 
 from Master.MasterDocuments master, 
      Master.DocumentCompartments comp, 
      Master.Programs prog 
 where doc.DocumentGuid=master.DocumentGuid and 
       master.DocumentGuid=comp.DocumentGuid and 
       comp.CompartmentID=prog.ProgramID and  
       not (prog.ADGroupName in ('P1', 'P3', 'P4', 'P7'))
 ))',

我現在正試圖弄清楚如何使用NHibernate QueryOver語法進行相同的查詢。 不幸的是,我沒有足夠的知識或經驗知道如何編寫它。 任何有關這方面的幫助將不勝感激!

我相信你想要這樣的東西:

IList<Guid> results = Session.QueryOver<Document>(() => documentAlias)
    .WithSubquery.WhereNotExists(
        QueryOver.Of<MasterDocument>()
                .Where(md => md.ID == documentAlias.MasterDocument.ID) // Not sure about this
            .JoinQueryOver(md => md.Compartments)
            .JoinQueryOver(cmp => cmp.AssociatedCompartment)
                .WhereNot(acmp => acmp.GroupName.IsIn(new[] { "P1", "P3", "P4", "P7" })))
    .Select(doc => doc.ID)
    .List<Guid>();

我不確定MasterDocument.IDDocument.MasterDocument.ID之間的比較是否正確,我評論過,但這應該讓你開始朝着正確的方向前進。

幾點說明:

  • 通常,您不能將QueryQver與LINQ語法一起使用。 它們看起來很相似,但它們是不同的查詢技術。
  • 有關QueryOver的基本介紹,請參閱nhibernate.info上的本指南 不幸的是,就官方文檔而言,這幾乎和你一樣好
  • 根據您提供的類,這假定了一些關於映射的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM