使用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
...但我不想丢失这种查询的编译时检查。
感谢。
答案 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;