使用NHibernate Linq查询制定内部联接的麻烦

时间:2014-01-13 22:56:33

标签: nhibernate linq-to-nhibernate

使用NHibernate 3.3.1.400,我在使用NHibernate的Linq提供程序表达什么是简单的SQL语句时遇到了问题。

我的域名模型如下:

public class Site
{
  public virtual Guid Id {get; set;}
  public virtual string Name {get; set;}
}

// a site has many filers
public class Filer
{
  public virtual Guid Id {get set;}
  public virtual Site Site {get; set;}
  public virtual string Name {get; set;}
}

// a filer has many filings
public class Filing
{
  public virtual Guid Id {get set;}
  public virtual Filer Filer {get; set;}
  public virtual DateTime FilingDate {get; set;}
}

//a filing has many items
public class Item
{
  public virtual Guid Id {get set;}
  public virtual Filing Filing {get; set;}
  public virtual DateTime Date {get; set;}
  public virtual decimal Amount {get; set;}
}

public class SearchName
{
  public virtual Guid Id {get set;}
  public virtual string Name {get; set;}
}

// there are potentially many NameLink objects tied to a single search name
public abstract class NameLink
{
  public virtual Guid Id {get set;}
  public virtual SearchName SearchName {get; set;}
}

public class NameLinkToFiler: NameLink
{
  public virtual Filer Filer {get; set;}
}

public class NameLinkToItem: NameLink
{
  public virtual Item Item {get; set;}
}

我的查询应该返回匹配的Item元素列表:

var query = session.Query<Item>()
  .Where(x => x.Filing.Filer.Site == mySite);

连接网站的连接 - &gt; Filer - &gt;归档 - &gt;项目通过我的映射工作得很好,但是当我尝试根据用户输入加入NameLinkToFiler或NameLinkToItem类时,问题就开始了。

如果用户想要使用文件管理器名称过滤查询结果,我想将Item查询的结果与此查询的结果一起加入:

var filerNameQuery = session.Query<NameLinkToFiler>()
.Where(q=>q.SearchName.Contains('some name'));

我希望NameLinkToFiler.Filer属性的结果加入Item.Filing.Filer属性,因此我的返回项目列表会减少。

注意:上面的'Contains'关键字是我正在使用的全文索引搜索here。它工作正常,我们假设filerNameQuery是IQueryable<NameLinkToFiler>

在直接SQL中执行此操作非常简单:

select filer.Name, filing.FilingDate, filer.Name, item.Date, item.Amount
from Search_Name searchNameForFiler, Search_Name searchNameForItem, Name_Link_Filer nameLinkFiler, 
Name_Link_Item nameLinkItem, Item item, Filing filing, Filer filer, Site s
where 
contains(searchNameForFiler.Name, :filerName) and searchNameForFiler.Id = nameLinkFiler.SearchNameId and nameLinkFiler.FilerId = filer.Id and
contains(searchNameForItem.Name, :itemName) and searchNameForItem.Id = nameLinkItem.SearchNameId and nameLinkItem.ItemId = item.Id
and item.FilingId = filing.Id
and filing.FilerId = filer.Id
and filing.SiteId = :site

...但我不想丢失这种查询的编译时检查。

感谢。

1 个答案:

答案 0 :(得分:7)

显然,答案是不使用lambda语法。

这很好用:

query = from t in parentItemQuery
   join l in Session.Query<NameLinkToFiler>() on t.Filing.Filer.Id equals l.Filer.Id
   join n in Session.Query<SearchName>() on l.SearchName.Id equals n.Id
   where sn.Contains(request.FilerName) 
   select t;