2010-07-21 76 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};