使用FetchMany的NHibernate查询返回不正确的结果

时间:2012-08-30 11:26:32

标签: nhibernate

我有两个相关实体:作业群组多对多关系。

我正在执行一个简单的查询来检索特定的作业及其关联的组(通过 GroupRecipients 属性):

var job = jobsRepo.Get()
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countA = job.GroupRecipients.Count;

结果是 countA == 2 ,它对应于数据库中的状态。

添加FetchMany时出现了第一个怪异:

var job = jobsRepo.Get()
                .FetchMany(x => x.GroupRecipients)
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countB = job.GroupRecipients.Count;

这导致 countB == 1 。 job.GroupRecipients集合中只显示一个项目,该项目与数据库中的状态相矛盾。

但它变得更有趣了。如果我连续运行以下内容:

var job = jobsRepo.Get()
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countA = job.GroupRecipients.Count;

var jobB = jobsRepo.Get()
                .FetchMany(x => x.GroupRecipients)
                .Where(j => j.Id == jobKey.Id)
                .FirstOrDefault();

var countB = jobB.GroupRecipients.Count;

然后我得到 countB == 2 ,预期的结果。再次使用countA删除该行会导致 countB == 1

更多信息: 我在无状态会话中的交易中执行查询。 NHibernate的版本是 3.3.1

这两个问题可归纳如下:

  1. FetchMany返回部分结果
  2. 一个查询以意外方式依赖于另一个查询。
  3. 非常欢迎对此行为的任何解释。

1 个答案:

答案 0 :(得分:1)

这似乎是LINQ提供程序处理FirstOrDefault的方式中的错误或不匹配 - 在我看来,它似乎为查询添加了一个LIMIT 1,这显然不适用于急切加载(产生OUTER JOIN)。

我通过显式转换为中间的可枚举来解决它:

var job = jobsRepo.Get()
                  .FetchMany(x => x.GroupRecipients)
                  .AsEnumerable()
                  .FirstOrDefault(j => j.Id == jobKey.Id);

这有点像黑客,但解决了这个问题。

可能,你的第二个例子是有效的,因为第一个例子将实体加载到缓存中,因此nHibernate不需要去数据库(并且遇到LINQ提供程序中的错误逻辑)。