2

我正在爲報告模型(SQL Server Reporting Services)創建數據源。 這些報告需要大量的連接和計算(比方說,計算像這樣花費的金錢參數,即數量A和數量B)......所有這些涉及子對象。在Linq/Lambda中寫入存儲過程(單元可測試但存儲過程存儲過程)。可能?

對於我來說,爲這段代碼編寫單元測試(即遍歷訂單集合,根據業務規則和子對象聚合信息等)是很有意義的。 要做到這一點,我希望我的代碼看起來約。像這樣

foreach (IOrder in Orders) 
    foreach (IOrderLine in IOrder.Orderlines) 
    ... 

    return ... 

然後測試返回值。

但是這段代碼並不是在報表視圖中使用的SQL ......當然...... 所以我在想,我可以在數據庫中插入一個.NET程序集。 這裏的問題當然是性能......我不想在C#中循環所有這些對象......太慢了。

因此,自然,Linq/Lambda/Expression樹似乎是我的答案。 正如我們所知道的那樣,當您將Linq轉換爲SQL時,會構建表達式樹,然後根據它們生成適當的SQL。因此,我可以使用lambda表達式在Linq中將我的代碼寫入到對象中,並在樣本集合(將表達式編譯爲.net)上單元測試此代碼,並在DB存儲過程中重複使用與Linq to SQL相同的代碼,所以在SQL Server內部它會爲我生成適當的SQL(就像Linq to SQL已經做到的那樣)...

然後,我可以從C#和高性能存儲中獲得單元測試和編寫域邏輯代碼的好處報告程序。

可能嗎? 我可以在SQL Server CLR存儲過程中使用Linq/Lambda嗎?任何人做過或知道如何使它工作? 我瘋了嗎?你知道更好的方法嗎?

感謝

附:我想現在我想出了這應該如何正確完成。據Udi Dahan說,如果我理解他是對的。數據庫應該是非規範化的,並且所有計算的字段應該位於表格中的對象上。 當子對象發生某些事情時(OrderLine添加),我的Customer對象應該接收一個事件並重新計算智能值(緩存並保存)。

然後報告直行向前,沒有邏輯和工作速度快...

回答

1

不,你不能在SQL CRL特效使用LINQ/LAMBDA - 這是基於不同版本的.NET和不支持這些命名空間。

1

所以,我可以寫我在LINQ的代碼 對象,使用lambda表達式, 單元測試此代碼上樣品 集合(具有表達 編譯到.NET),並且重複使用相同的 代碼的LINQ在SQL存儲過程中存儲 過程,因此SQL Server內部的 它會爲我生成適當的SQL (因爲Linq to SQL已經這樣做)...

這個計劃一直很好,直到你建議從存儲過程中調用CLR代碼。從數據庫進程本身運行CLR代碼會在版本控制,配置和數據庫穩定性方面產生很多問題......如果這樣做的話,問題太多。

你的動機是有使用存儲過程的好處,一般速度更快。如果這些存儲過程依次運行CLR代碼,它們不會比在本地過程中運行的CLR代碼更快。

使用LINQ生成的表達式在技術上會比存儲的特效消耗更多的CPU週期。這是因爲每次運行查詢時,數據庫引擎都必須重新生成執行計劃。通常情況下,您的數據庫服務器位於單獨的計算機上,但不受CPU限制(它將受限於磁盤或網絡容量),因此這不是真正的性能問題。這可能是因爲如果你在一臺機器上運行數據庫服務器而不是其他所有的東西,但是不要試圖用一些如此複雜的東西來解決這個問題,直到它成爲一個真正的問題。

如果您想減少生成報告的開銷,Udi的建議可能是適當的。首先要考慮兩個重要的副作用。首先,是否可以承擔增加預生成報告字段的操作的性能開銷?更大的問題是它將報告邏輯與運行目標系統的代碼結合在一起。這會阻止您在不更新業務代碼的情況下更新報告代碼,並假設報告的代碼在投入生產後立即運行。