【问题标题】:Complex Linq-to-SQL where condition help条件帮助的复杂 Linq-to-SQL
【发布时间】:2011-03-19 04:35:56
【问题描述】:

我尝试在 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() 返回不正确的记录计数,因为记录可能匹配多个表达式。我将尝试重新安排逻辑并创建一个新的 TSQL 版本,它可以帮助我在 LINQ 中找到解决方案。

欢迎提出想法。

【问题讨论】:

  • 在你说 SQL 版本令人困惑和丑陋之前先写出 LINQ 替代方案:P
  • 我可能错过了,但我没有看到您在 CompanyList 上实际使用您的加入...
  • CompanyList 上的联接是限制性联接。数据并不像应有的那么干净,所以我加入了表格以确保只有好东西才能回来。
  • 啊。凉爽的。我必须检查一下,但我认为在 WHERE 子句中添加“AND r.company IN (SELECT company FROM CompanyList)”可能会更高效,但它可能是一个清洗...

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


【解决方案1】:

既然 LINQ-to-SQL 通过ExecuteQuery 支持 TSQL - 为什么要重新编写有效的东西?复杂的查询可能值得一些手动操作。我会保持“原样”,然后简单地替换:

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

调用时会被注入

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

【讨论】:

    【解决方案2】:

    我不确定 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};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      相关资源
      最近更新 更多