2010-07-21 90 views
1

我有一個令人困惑的SQL選擇語句(難看),我試圖寫在LINQ中。我正在努力獲取將執行的單個統計信息,而不是將預先選定的數據放入必須發送回服務器的列表中。複雜Linq到SQL在條件幫助

DECLARE @StartDate DATETIME ; 
DECLARE @EndDate DATETIME ; 
SET @pStartDate = '20100501' 
SET @pEndDate = '20100531' 

SELECT r.company ,r.trandate ,r.currency ,r.account ,r.credit ,r.debit 
FROM dbo.Register r 
INNER JOIN dbo.CompanyList c ON r.company = c.company 
WHERE 
r.trandate BETWEEN @pStartDate AND @pEndDate 
AND LEN(r.currency) > 0 
AND ( 
    (r.account = 'XXX-ZZZ') 
    OR 
    (LEFT(r.account, 3) IN (SELECT LEFT(code, 3) FROM dbo.investments)) 
    OR 
    (r.account IN ( 
     SELECT account FROM dbo.CompanyInfo WHERE company = r.company 
        AND ((dateclosed IS NULL) 
        OR dateclosed >= @pStartDate))) 
    ) 

這是一個包含問題代碼的示例 - 帶有三個OR表達式的WHERE子句。我試過使用三個不同的查詢,然後concat()或union()返回不正確的reccord計數,因爲記錄可能匹配多個表達式。我將嘗試重新排列邏輯並創建一個新的TSQL版本,這可能會幫助我在LINQ中找到解決方案。

想法歡迎。

+0

寫出LINQ替代你說的SQL版本是令人困惑的和醜陋的面前:P – Andomar 2010-07-21 19:21:02

+0

我可能已經錯過了,但我沒有看到任何地方,你實際使用您的加盟對CompanyList ... – 2010-07-21 19:36:34

+0

的加入CompanyList是一種限制性連接。數據並不像應該那樣乾淨,所以我加入到試圖確保只有好東西回來的表格中。 – secoast 2010-07-21 21:17:35

回答

4

由於LINQ-to-SQL通過ExecuteQuery支持TSQL - 爲什麼要重新編寫一些有效的東西?複雜的查詢可能值得有點手搖。我會見好就收「原樣」,並簡單地替代:

SET @pStartDate = {0} 
SET @pEndDate = {1} 

,當你調用

var data = ctx.ExecuteQuery<RegisterQueryResult>(tsql, startDate, endDate); 
1

將被注入我不知道子字符串中的LINQ轉換到SQL那麼你的左邊部分可能根本不會翻譯。事實上,我相對肯定他們不會,所以如果你只是想克服這個麻煩,馬克的解決方案可能是最好的。也就是說,如果您假定創建了一個上下文對象,並且您大多數都使用表名和列名的默認值,那麼可能會工作

var registers = from reg in context.Registers 
       where reg.Trandate >= pStartDate && reg.Trandate <= pEndDate 
       && ((reg.Account == regValue) 
        || ((from investment in context.Investments 
         select investment.Code.Substring(0,3)).Contains(reg.Account.Substring(0,3))) 
        || ((from cInfo in context.CompanyInfo 
         where cInfo.Company == reg.Company && ((cInfo.DateClosed == null) || cInfo.DateClosed.Value == pStartDate) 
         select cInfo.Account).Contains(reg.Account))) 
       select New {reg.Company, reg.Trandate, reg.Currency, reg.Account, reg.Credit, reg.Debit};