复杂的Linq-to-SQL,其中有条件帮助

时间:2010-07-21 19:17:18

标签: c# linq-to-sql tsql where-clause

我正在尝试在LINQ中编写一个令人困惑的SQL select语句(丑陋)。我正在努力获得一个将执行的单个语句,而不是预先选择的数据到我必须发送回服务器的列表中。

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中找到解决方案。

欢迎提示。

2 个答案:

答案 0 :(得分:4)

由于LINQ-to-SQL通过ExecuteQuery支持TSQL - 为什么要重写一些有效的东西?复杂的查询可能值得进行一些手动操作。我会“按原样”离开,只需替换:

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

将在您致电

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

答案 1 :(得分:1)

我不确定SubString是否会将Linq转换为SQL,因此您的LEFT部分可能根本不会翻译。事实上,我相对肯定他们不会这么做,所以Marc的解决方案可能是最好的,如果你只是想要克服困难。也就是说,如果您假设已经创建了一个上下文对象,并且您主要采用表名和列名的默认值,则以下可能有效。

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};