我讀過DDD Evans,並且正在使用C#和Entity Framework 4.1 + LINQ試驗一個聚合根存儲庫設計。我應該在EF 4.1 + LINQ中使用DDD聚合根存儲庫嗎?
但是,我擔心發送到數據庫的實際查詢。我正在使用SQL 2008 R2,並運行SQL事件探查器來檢查數據庫響應LINQ代碼所做的事情。
考慮使用Person和EmailAddress的簡單2實體設計。一個人可以有零到多個EmailAddress,而一個EmailAddress只能有一個Person。 Person是聚合根,因此不應該有電子郵件地址的存儲庫。電子郵件地址應該從Person存儲庫中選出(根據DDD Evans)。
爲了比較,我確實爲電子郵件地址設置了一個臨時存儲庫。下面的代碼行:
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 emailString = "[email protected]";
var emailEntity = _tempEmailRepository.All.SingleOrDefault(e =>
e.Value.Equals(emailString, StringComparison.OrdinalIgnoreCase));
...根據探查執行一個乾淨的SQL查詢:
var emailEntity = _personRepository.All.SelectMany(p => p.Emails)
.SingleOrDefault(e => e.Value.Equals(emailString,
StringComparison.OrdinalIgnoreCase))
這讓我在運行相同的實體,但不同的命令顯示了在SQL事件探查器:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
FROM [dbo].[Person] AS [Extent1]
除了從人選擇上面的查詢,有許多的「RPC:已完成」事件,一個用於在DB每個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
我的測試分貝有14行在dbo.EmailAddress中,並且有14個不同的RPC:已完成的調用,每個都有不同的@ EntityKeyValue1值。
我假設這對SQL性能不利,因爲dbo.EmailAddress表獲得更多行,更多的這些RPC將在db上調用。在EF 4.1 + LINQ中使用DDD聚合根存儲庫還有另一種更好的方法嗎?
更新:解決
的問題是,所有的財產返回一個IEnumerable<TEntity>
。在這改爲IQueryable<TEntity>
之後,LINQ一下子就進入並選擇了整個Person + Emails。但是,我必須鏈接.Include(p => p.Emails)才能從All返回IQueryable。
你從'All'屬性返回什麼? – 2011-05-18 15:26:36
好問題。當我發佈這個所有返回一個IEnumerable。將其更改爲IQueryable並查看其差異。將發佈更新。 –
danludwig
2011-05-18 19:23:17