我应该在EF 4.1 + LINQ中使用DDD聚合根存储库吗?
|
我已经读过DDD Evans,并且尝试使用C#和Entity Framework 4.1 + LINQ进行汇总根存储库设计。
但是,我担心发送到数据库的实际查询。我正在使用SQL 2008 R2,并运行SQL Profiler来检查数据库响应LINQ代码正在做什么。
考虑一个使用Person和EmailAddress的简单2实体设计。一个人可以有零到多个电子邮件地址,并且一个电子邮件地址必须恰好有一个人。 Person是聚合根,因此不应有电子邮件地址的存储库。电子邮件地址应从“个人”存储库中选择(根据DDD Evans)。
为了进行比较,我确实为电子邮件地址设置了一个临时存储库。下面的代码行:
var emailString = \"someone@somewhere.com\";
var emailEntity = _tempEmailRepository.All.SingleOrDefault(e =>
e.Value.Equals(emailString, StringComparison.OrdinalIgnoreCase));
...根据事件探查器执行一个不错的干净的SQL查询:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Value] AS [Value],
[Extent1].[IsDefault] AS [IsDefault],
[Extent1].[IsConfirmed] AS [IsConfirmed],
FROM [dbo].[EmailAddress] AS [Extent1]
我可以使用以下代码从人员存储库中选择电子邮件:
var emailEntity = _personRepository.All.SelectMany(p => p.Emails)
.SingleOrDefault(e => e.Value.Equals(emailString,
StringComparison.OrdinalIgnoreCase))
这使我在运行时具有相同的实体,但是在SQL Profiler中显示了不同的命令:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
FROM [dbo].[Person] AS [Extent1]
除了从Person中选择的上述查询之外,还有许多\“ RPC:Completed \”事件,对于数据库中的每个EmailAddress行,一个事件:
exec sp_executesql N\'SELECT
[Extent1].[Id] AS [Id],
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Value] AS [Value],
[Extent1].[IsDefault] AS [IsDefault],
[Extent1].[IsConfirmed] AS [IsConfirmed],
FROM [dbo].[EmailAddress] AS [Extent1]
WHERE [Extent1].[PersonId] =
@EntityKeyValue1\',N\'@EntityKeyValue1 int\',@EntityKeyValue1=1
exec sp_executesql N\'SELECT
[Extent1].[Id] AS [Id],
[Extent1].[PersonId] AS [PersonId],
[Extent1].[Value] AS [Value],
[Extent1].[IsDefault] AS [IsDefault],
[Extent1].[IsConfirmed] AS [IsConfirmed],
FROM [dbo].[EmailAddress] AS [Extent1]
WHERE [Extent1].[PersonId] =
@EntityKeyValue1\',N\'@EntityKeyValue1 int\',@EntityKeyValue1=2
我的测试数据库在dbo.EmailAddress中有14行,并且有14个不同的RPC:Completed调用,每个调用具有不同的@ EntityKeyValue1值。
我假设这对SQL性能不利,因为随着dbo.EmailAddress表获得更多的行,将在数据库上调用更多的RPC \。是否还有另一种更好的方法将DD 4.1聚合根存储库与EF 4.1 + LINQ一起使用?
更新:已解决
问题在于All属性返回了IEnumerable<TEntity>
。将其更改为IQueryable<TEntity>
之后,LINQ参与进来,一口气选择了整个“人+电子邮件”。但是,在从All返回IQueryable之前,我必须链接.Include(p => p.Emails)。
没有找到相关结果
已邀请:
1 个回复
郸身