2010-06-23 48 views
3

我在much more long-winded way a few days ago中問過這個問題,考慮到長度,我沒有得到答案的事實並不令人驚訝,所以我想我會更加註意。1000+ Linq查詢或數據庫中的邏輯......這更糟?

我必須根據他們對特定客戶的分配來決定如何顯示用戶。域對象看起來像這樣大大簡化的例子:

public class Customer 
{ 
    public string Name { get; set; } 
    public IEnumerable<Users> AssignedUsers { get; set; } 
} 

在現實世界中,我也會評估他們是否有權限(使用安全標誌按位比較)來查看,即使他們AREN這個特定的客戶沒有直接分配給它。

我想在這裏堅持domain-driven design(DDD)的原則。另外,我使用LINQ to SQL來進行數據訪問。在我的服務層,我向用戶提供請求客戶名單的信息,目前約有1000個項目,每月增長約2%。

如果我對服務層中的邏輯保持嚴格,我將需要使用Linq來執行.Where,它將評估AssignedUsers列表是否包含請求列表的用戶。當系統列舉時,這將導致每個Customer的級聯查詢。我沒有做任何測試,但這似乎效率低下。

如果我對數據中的邏輯沒有依據,那麼我可以簡單地使用GetCustomersByUser()方法,該方法將同時執行一個類型的SQL查詢並評估安全性。這肯定會更快,但現在我正在談論邏輯蔓延到數據庫中,這可能會在稍後造成問題。

我敢肯定,這是人們在推出Linq時出現的一個常見問題......有哪些方法更好的建議?在我的數據庫中,Linq的多重查詢的性能好於邏輯嗎?

+2

如果你大多試圖檢索分配給用戶的客戶,你應該不會修改你的對象,並擁有一個帶有AssignedCustomers列表的用戶? – Mathias 2010-06-23 22:27:26

+0

例如,用戶分配的實際數據 - 他們收到的佣金。因此,不管您以哪種方式查看它,多對多關係都需要一個單獨的賦值對象。我們也批發,因此用戶是我們真正的客戶。 – 2010-06-24 11:26:29

+0

我在想更多關於那個評論......實際上可能有一種方法來觸發它,並使Assignment對象和它的數據專注於客戶而不是用戶...... – 2010-06-24 11:42:06

回答

5

哪個更糟? 取決於你問的人。

可能如果你問DDD超純化他們會說數據庫中的邏輯更糟糕。

如果你詢問其他人,恕我直言,特別是最終用戶,實用開發人員以及爲硬件和軟件開發付費的人員,他們可能會說大幅度的性能下降會更糟。

DDD有許多讚揚它,因爲這樣做很多其他的設計方法,但他們所有往下掉,如果你武斷地跟着他們去想出一個「純粹」的設計在現實世界中考慮犧牲點,如表現。

如果您確實需要對數據執行這種查詢,那麼數據庫幾乎可以肯定地是遠的在執行任務時更好。

另外,你有沒有「錯過了一個把戲」在這裏。你的設計,但是DDD,實際上是不正確的?

整體 - 適當使用您的工具。通過一切手段努力保持邏輯與服務層的分離,但不是在邏輯處理大量數據庫設計工作的時候。

+2

+1「他們都跌倒如果你教條跟隨他們「 – 2010-06-23 22:37:47

+0

關於設計有趣的問題......我想知道DDD是否真的是最好的模式,因爲這本質上是一個數據庫應用程序,業務邏輯主要是工作流和狀態管理,做貨幣計算的部分。因此,「域」本質上是關係型的(然後再次,我認爲什麼域不是),並且我可能是鞋關係型關係數據庫原理進入我的域對象。 – 2010-06-24 11:36:19

+0

@downvoter - 爲什麼倒票?我有興趣知道你不同意,所以請留下評論。 – 2010-06-26 17:41:11

1

如果AssignedUser正確映射(即,聯合是由Linq2SQL設計器生成的,或者你有AssosiationAttribute的標記屬性(或者其他一些來自http://msdn.microsoft.com/en-us/library/system.data.linq.mapping(v=VS.90).aspx命名空間的命令,我現在還不確定),Linq2Sql會將linq查詢轉換爲SQL命令,並且不會通過每個客戶的AssingedUser進行迭代。

您也可以使用「反轉」查詢像

from c in Customer 
join u in Users on c.CustomerId equals u.AssignedToCustomerId // or other condition links user to customer 
where <you condition here> 
select c 
3

LINQ是一種抽象,它包裝了一堆的功能集成到一個漂亮的小包裝,頂部一顆大心臟。

隨着任何抽象,你會得到開銷,主要是因爲事情並不像你或我想要的那樣高效。 MS在使LINQ非常高效方面做得非常出色。

邏輯應該是它在哪裏needed.Pure是好的,但如果你是一個提供產品或服務,你必須有注意以下幾點(這是在沒有特定的順序):

  1. 維護。在發佈之後,你是否可以輕鬆地完成一些工作,而不會將整個事情分開。
  2. 可擴展性。
  3. 性能
  4. 可用性。

3號是使用網絡時最大的一個方面。你會在SQL Server上做三角?你會根據輸入參數過濾結果嗎?是。

SQL Server用於處理大量查詢,過濾,排序和數據挖掘。它欣欣向榮,所以讓它做到。

這不是一個邏輯蔓延,它把功能放在它所屬的地方。

+1

+1「這不是一個邏輯蠕變,它將功能放在它所屬的位置。」 – 2010-06-23 22:47:09

0

我會親自去存儲proc。這是工作的正確工具。 不使用它可能是一個不錯的設計選擇,但在我看來,設計範例可以引導您,而不是限制您。 另外,老闆只關心性能:-)

1

如果我嚴格的保守邏輯在我的業務層,我將需要使用LINQ做。凡用來評估AssignedUsers列表中是否包含用戶請求清單。這將導致系統列舉的每個客戶的級聯查詢。我沒有做任何測試,但這似乎效率低下。

應該不需要枚舉本地客戶收集。

LinqToSql的主要目的是讓你聲明服務層中的邏輯,並在數據層中執行該邏輯。

int userId = CurrentUser.UserId; 

IEnumerable<Customer> customerQuery = 
    from c in dataContext.Customers 
    where c.assignedUsers.Any(au => au.UserId = userId) 
    select c; 

List<Customer> result = customerQuery.ToList(); 
1

我認爲您的模型最好被描述爲Customer類和User類之間的多對多關係。每個用戶引用相關客戶的列表,並且每個客戶引用相關用戶的列表。從數據庫的角度來看,這是使用連接表來表示的(根據微軟的LINQ to SQL術語,他們稱之爲「連接表」)。

多對多關係是LINQ to SQL不支持開箱即用的功能之一,如果嘗試生成DBML,您可能會注意到這一點。

幾個博客已經發布瞭解決方法,包括一個來自MSDN(不幸的是沒有任何具體的例子)。有一個博客(2部分後),它緊貼在MSDN建議:

http://blogs.msdn.com/b/mitsu/archive/2007/06/21/how-to-implement-a-many-to-many-relationship-using-linq-to-sql.aspx

http://blogs.msdn.com/b/mitsu/archive/2008/03/19/how-to-implement-a-many-to-many-relationship-using-linq-to-sql-part-ii-add-remove-support.aspx