0

我有两个相关实体:JobGroup,具有多对多关系。

我正在执行一个简单的查询来检索特定的作业及其关联的组(通过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. 一个查询以一种意想不到的方式依赖于另一个查询。

对此行为的任何解释都非常受欢迎。

4

1 回答 1

2

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

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

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

这有点骇人听闻,但可以解决问题。

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

于 2013-05-20T11:41:36.957 回答