Комплекс Linq-to-SQL, где условие помогает - PullRequest
1 голос
/ 21 июля 2010

У меня сбитый с толку оператор SQL (некрасиво), который я пытаюсь написать в LINQ. Я работаю, чтобы получить единую статистику, которая будет выполнять, а не предварительно выбранные данные в списки, которые я должен отправить обратно на сервер.

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) ) )
    )

Это пример, содержащий код проблемы - предложение WHERE с тройным выражением ИЛИ. Я попытался использовать три разных запроса, а затем concat () или union (), который возвращает неверное количество записей, потому что запись может соответствовать нескольким выражениям. Я собираюсь попробовать изменить логику и создать новую версию TSQL, которая может помочь мне найти решение в LINQ.

Идеи приветствуются.

Ответы [ 2 ]

4 голосов
/ 21 июля 2010

Поскольку LINQ-to-SQL поддерживает TSQL через ExecuteQuery - зачем переписывать то, что работает? Сложные запросы вполне могут заслуживать немного ручного запуска. Я бы просто оставил "как есть" и просто подставил:

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

, который будет введен при вызове

var data = ctx.ExecuteQuery<RegisterQueryResult>(tsql, startDate, endDate);
1 голос
/ 21 июля 2010

Я не уверен, что SubString будет переводить в 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};
...