使用LINQ-to-NHibernate可以缩小FetchMany()
返回的范围吗?
给出以下类结构
public class Foo
{
public virtual int Id { get; set; }
public virtual IList<Bar> Bars { get; set; }
}
public class Bar
{
public virtual string Description { get; set; }
}
我该怎么做:
session.Query<Foo>()
.Where(foo => foo.Id > 30)
.FetchMany(foo =>
foo.Bars.Where(bar => bar.Description.StartsWith("x")));
NHibernate将返回所有Foo的Id&gt; 30,对于那些Foo所有附加的Bar,其中Bar的描述以字母“x”开头?
我发现一些使用旧QueryOver()
内容的帖子,但我明确地想要使用NHibernate的LINQ提供程序。
有什么想法吗?
更新
我想我需要澄清我想要的结果。
<Foo Id="1">
<Bar Description="x1"/>
<Bar Description="b1"/>
</Foo>
<Foo Id="31">
<Bar Description="x2"/>
<Bar Description="x3"/>
<Bar Description="b2"/>
</Foo>
<Foo Id="32">
<Bar Description="b3"/>
</Foo>
根据上面列出的数据,我希望得到以下结果
<Foo Id="31">
<Bar Description="x2"/>
<Bar Description="x3"/>
</Foo>
<Foo Id="32"/>
附加的Where子句应该仅适用于Bar!它不应该进一步缩小Foo的名单!只需减少FetchMany()
返回的内容。
答案 0 :(得分:1)
我很确定你对当前的linq提供商运气不好 - 但是对于非linq(和交叉)选项,你可能想看一下包含的filter功能在NHibernate中 - 它可能是在大型/复杂项目中实现这一点的最佳选择。
答案 1 :(得分:1)
var query = from foo in session.Query<Foo>()
where foo.Id >30
from bar in foo.Bars
where bar.Description.StartsWith("x")
select new { Id = foo, Bar = bar};
var results = query.ToList().ToLookup(x => x, x => x.Bar);
foreach(var foo in results.Keys)
{
var barsWhichStartWithX = results[foo];
//DO STUFF
}
虽然这可能会产生效率低下的SQL(我不使用nHibernate,所以我不知道)。你也可以尝试这个...而且上面会错过没有酒吧的foos。
var foosQuery = session.Query<Foo>().Where(foo => foo.Id > 30);
var foos = foosQuery.Future();
var barsQuery = from f in foosQuery
from bar in foo.Bars
select new { Id = foo.Id, Bar = bar};
var foosDict = foos.ToDictionary(x => x.Id);
var bars = barsQuery.ToList().ToLookup(x => foosDict[x.Id], x => x.Bar);
foreach(var foo in foos)
{
var barsWhichStartWithX = bars[foo];
//DO STUFF
}
答案 2 :(得分:0)
也许完全你所追求的是什么,但值得考虑的是NHibernate.CollectionQuery库。
它允许您使用Linq在实体上查询未初始化的NHibernate集合 - 但需要额外的查询/往返才能获取它们(与FetchMany不同,它在同一往返中抓取整个集合)。
答案 3 :(得分:0)
您需要从子对象到父对象的引用。
var result = from foo in session.Query<Foo>().FetchMany(f => f.Bars)
from bar in session.Query<Bar>()
where foo.Id == bar.FooId && // FooId is missing in your entity
foo.Id > 30
bar.Description.StartsWith("x")
select foo;