Nhibernate存在于queryOver的地方

Nhibernate存在于queryOver的地方,nhibernate,queryover,Nhibernate,Queryover,我有以下对象 public class Document { public Guid Id { get; set; } public ISet<Tag> Tags { get; set;} ... } public class Tag { public Guid Id { get; set;} } 这是一个多对多关系,但我没有中间的DocumentTag对象。 我试图使用QueryOver语法返回所有包含一组标记的文档。这是我到目前为止所拥有的

我有以下对象

public class Document
{
    public Guid Id { get; set; }
    public ISet<Tag> Tags { get; set;}
    ...
}

public class Tag 
{
    public Guid Id { get; set;} 
}
这是一个多对多关系,但我没有中间的DocumentTag对象。 我试图使用QueryOver语法返回所有包含一组标记的文档。这是我到目前为止所拥有的

Guid[] tagsThatMustMatch = ...;
var result = Session.QueryOver<Document>()
               .WithSubquery
               .WhereExists(QueryOver.Of<Tag>().Where(t => tagsThatMustMatch.Contains(t.Id))
               .List()
我在表达要求时遇到困难。我知道我必须动态构造一个查询,该查询将为每个必须匹配的标记提供一个WhereExists。这些问题需要加以讨论。我遇到的另一个问题是WhereExists方法需要接受DetachedQuery。但是我没有办法限制它只查看这个文档中没有所有标记的标记

有没有什么例子可以让我看到如何做这样的事情?

使用IN-无需调整实体定义

让我们首先这样声明子查询:

Guid[] tagsThatMustMatch = ...;

var subQuery = QueryOver.Of<Tag>()
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
  .Select(t => t.Id); // tag ID projection
或者至少是表示DoucmentID的Guid

public class Tag 
{
    public Guid Id { get; set;} 
    public Guid DocumentId { get; set; }
}
让我们假设第一个,然后我们可以像这样使用子查询

Guid[] tagsThatMustMatch = ...;

// Essential alias of the parent Document
Document document = null;

var subQuery = QueryOver.Of<Tag>()
 .Where(t => t.Document.Id == document.Id) // or t.DocumentId = document.Id
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
 .Select(t => t.Id); // tag ID projection
var query = session
    .QueryOver<Document>(() => document) // alias used in subquery
    .WithSubquery                        // needed to filter by parent id
        .WhereExists(subQuery)
    ...
这是子查询仅在与文档相关的标记上正确返回true的唯一方法。exist查询的外观将与此不同

Guid[] tagsThatMustMatch = ...;

// Essential alias of the parent Document
Document document = null;

var subQuery = QueryOver.Of<Tag>()
 .Where(t => t.Document.Id == document.Id) // or t.DocumentId = document.Id
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
 .Select(t => t.Id); // tag ID projection
var query = session
    .QueryOver<Document>(() => document) // alias used in subquery
    .WithSubquery                        // needed to filter by parent id
        .WhereExists(subQuery)
    ...
使用IN-无需调整实体定义

让我们首先这样声明子查询:

Guid[] tagsThatMustMatch = ...;

var subQuery = QueryOver.Of<Tag>()
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
  .Select(t => t.Id); // tag ID projection
或者至少是表示DoucmentID的Guid

public class Tag 
{
    public Guid Id { get; set;} 
    public Guid DocumentId { get; set; }
}
让我们假设第一个,然后我们可以像这样使用子查询

Guid[] tagsThatMustMatch = ...;

// Essential alias of the parent Document
Document document = null;

var subQuery = QueryOver.Of<Tag>()
 .Where(t => t.Document.Id == document.Id) // or t.DocumentId = document.Id
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
 .Select(t => t.Id); // tag ID projection
var query = session
    .QueryOver<Document>(() => document) // alias used in subquery
    .WithSubquery                        // needed to filter by parent id
        .WhereExists(subQuery)
    ...
这是子查询仅在与文档相关的标记上正确返回true的唯一方法。exist查询的外观将与此不同

Guid[] tagsThatMustMatch = ...;

// Essential alias of the parent Document
Document document = null;

var subQuery = QueryOver.Of<Tag>()
 .Where(t => t.Document.Id == document.Id) // or t.DocumentId = document.Id
 .WhereRestrictionOn(t => t.Id).IsIn(tagsThatMustMatch)
 .Select(t => t.Id); // tag ID projection
var query = session
    .QueryOver<Document>(() => document) // alias used in subquery
    .WithSubquery                        // needed to filter by parent id
        .WhereExists(subQuery)
    ...

-1因为有3个问题:1他要求存在,不在或加入,2在从T中选择Id中做X,其中Id在。。。“几乎”与在…中执行X相同吗。。。3使用连接来做这件事很慢,应该使用EXIST。@DiegoJancic,我用你建议的方法扩展了我的答案。这并不是那么简单,因为我们必须扩展域模型来实现它,但现在它将按照您提到的更好的sql语句来做。非常感谢您对为什么否决的评论。我很佩服你添加了评论!谢谢你帮我改进它。回答得很好。更改为+1.-1,因为有3个问题:1他要求存在,不在或加入,2在从T中选择Id中执行X,其中Id在。。。“几乎”与在…中执行X相同吗。。。3使用连接来做这件事很慢,应该使用EXIST。@DiegoJancic,我用你建议的方法扩展了我的答案。这并不是那么简单,因为我们必须扩展域模型来实现它,但现在它将按照您提到的更好的sql语句来做。非常感谢您对为什么否决的评论。我很佩服你添加了评论!谢谢你帮我改进它。回答得很好。更改为+1。