2

我正在尝试将聚合根模式应用于我的域。我正在使用带有 POCO 实体生成器的实体框架 4。

我有两个实体: MailingTask EmailLog 具有一对多的关系。(MailingTask 有很多 EmailLogs)。EF4 在 MailingTask 上生成一个导航属性:

public virtual ICollection<EmailLog> EmailLogs

在我的模型中,我永远不想直接访问 EmailLogs,总是通过其父 MailingTask。这是通过以下方式强制执行的:

  • 只有一个 MailingTask 存储库,所以我不能直接查询 EmailLogs 表。
  • 仅通过此导航属性获取 EmailLogs。

我有时需要计算 MailingTask 的 EmailLogs 数量。这是通过在导航属性上使用 LINQ 来实现的:

mailingTask.EmailLogs.Count();

但这在应用程序端(而不是数据库服务器)执行。(而且它非常昂贵,因为我有很多用于 MailingTask 的 EmailLogs。)我阅读了一些关于这种行为的帖子,似乎 EF4 导航属性不能用作 IQueryable(在数据库端执行)。当您访问导航属性时,EF4 会在内存中加载所有包含所有列的条目,并在内存中应用 LINQ 表达式。对于 Count() 语句,这很痛苦。

我相信我将不得不改变我的模型以适应这种专门的查询(可能添加一个具有查询能力的 EmailLogsRepository)。对我来说,似乎 EF4 不能很好地支持聚合根模式。或者我可能遗漏了一些关于聚合根模式以及它应该如何在 EF4 方面实现的内容......

有没有人遇到过这种情况并能够解决这个问题?nHibernate 或其他 ORM 是否更好地支持这一点?

4

1 回答 1

0

NHibernate 确实支持Count()“本机”,因为它被映射到 SQL“Select COUNT(*) ..”查询,并且不需要实现所有实体 - 这是 EF 对同一查询所做的。

对于实体框架,有一种解决方法可以实现相同的效果,此处详细介绍。计数查询将如下所示:

int logCount = context.Entry(mailingTask)
                      .Collection(p => p.EmailLogs)
                      .Query()
                      .Count();

尽管对于这个查询,这将需要更改模型,因为您不能Count()直接使用导航属性/ - 这是一个主要缺点,需要在 EF 中尽快修复。

于 2011-05-09T15:53:04.953 回答