LINQ-to-NHibernate FetchMany的where子句?

时间:2013-07-13 15:12:41

标签: linq nhibernate linq-to-nhibernate

使用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()返回的内容。

4 个答案:

答案 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;
相关问题