简体域名:QueryOver集合包含所有值
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
}
我知道这有点令人费解,但存在这样的,因为我们已经通过把某些记录(如文件)为不同的处理安全问题的模式数据库对应于它们所属的程序/舱(可互换术语)。 MasterDocument,Program和DocumentCompartment的表位于“主”数据库中,其中包含所有隔离专区的信息,而几个不同的数据库则分别包含自己的Documents表。无论如何,在这个问题上:
我想构建一个查询,我传递了一个组名列表,并且我只想要那些没有包含在该组名列表中的关联隔离的文档。
作为一个例子:
文档1与隔室相关联的P1
文档2与P2,P3相关联,并且P7
文档3与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));
(同样在上面记:如果我尝试封装在文档类是逻辑和方法传递给“去哪儿”方法,例如返回Session.Query()。其中(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'))
))',
我现在TR要弄清楚如何使用NHibernate QueryOver语法来完成相同的查询。不幸的是,我没有足够的知识或经验知道如何编写它。任何帮助,将不胜感激!
那么,*似乎*工作。我没有真正创建任何单元测试,以确保它做我想做的事情,但调用我的查询方法的单元测试至少现在不会在NHibernate代码中引发异常。 –
Btw,你是否有可能在Document类中封装LINQ逻辑有任何评论,所以我可以这样调用它:Session.Query()。Where(doc => doc.CanAccess(groups))?我真正想要做的是拦截我们的查询,检查T是否是特定类型(例如ISecurable,它定义了bool CanAccess(...)),并插入表达式以仅当我可以访问'它。如上所述,内联逻辑起作用,但试图在方法内调用该逻辑不会。 –
通常,您不能从QueryOver查询中调用实体的方法。将QueryOver视为直接转换为SQL。因此,'CanAccess'在SQL查询中没有意义。你将不得不水合实体和*然后*调用该方法。 –