Порт SQL в LINQ с левым внешним соединением с агрегацией и побитовой фильтрацией - PullRequest
0 голосов
/ 11 ноября 2010

У меня следующий запрос:

;WITH valRules AS   
(   SELECT vr.valRuleID, Count(*) AS totalRows, Sum(vt.test) AS validRows  
    FROM (SELECT NULL AS x)    AS x  
    JOIN #itemMap              AS IM  
      ON IM.lngitemID       = 1  
    JOIN tblValidationRule     AS vr  
      ON IM.RuleID          = vr.valRuleID  
    JOIN tblValidationRuleDetl AS vrd  
      ON vr.valRuleID       = vrd.valRuleID
    LEFT JOIN #ValTest         AS vt  
      ON vrd.type           = vt.type     
     AND vrd.typeSequence   = vt.typeSequence  
     AND vrd.valRule        & vt.Response > 0   
     OR (vrd.valrule = 0 AND vt.response = 0 )  
     GROUP BY vr.valRuleID  
)  
SELECT Count(*)   
    FROM valrules  
    WHERE totalrows = validRows

Обратите внимание на CTE и битовый оператор в условии левого соединения.Как это используется в настоящее время в хранимой процедуре, которая получает значения из приложения C # в форме переменной XML.Переменная XML помещается в таблицу #valTest.Все столбцы имеют тип данных INT.Если vt.Response действителен для vaRule, результат & будет больше нуля.(т.е. 31 & 8 = 8, но 12 & 2 = 0).Столбец vt.Test содержит число 1 для каждой строки, так что его можно суммировать (нули автоматически исключаются), чтобы получить количество проверок, которые проходят по правилу.Каждое правило имеет ряд атрибутов, которые должны пройти проверку для успеха.Если количество атрибутов равно пропущенным атрибутам, мы добьемся успеха.

В попытке сократить количество обращений к базе данных цель состоит в том, чтобы кэшировать ВСЕ правила в ASP.NET кеш и обрабатывать проверки локально.Разработчики просят ненормализованную версию данных проверки с утверждением, что операция на основе SQL Set не является простой задачей в C # с Linq.Из того, что я изучил, я бы согласился.На данный момент мое исследование показывает, что побитовое сравнение в условии соединения является особенно проблематичным.

Главный вопрос - как это можно преобразовать в нечто, использующее Linq на стороне C #?Или есть более эффективные способы решения этой проблемы на стороне клиента, и Linq не является одним из них (то есть просто дает им единообразные данные)?

спасибо

1 Ответ

0 голосов
/ 11 ноября 2010

LINQ-to-SQL не собирается делать что-то столь же индивидуальное, как этот запрос.Что не является критикой ни LINQ-to-SQL, ни запроса: просто существуют ограничения.

Есть два способа, которыми я бы подошел к этому:

1: как параметризованный TSQLзапрос через ExecuteQuery<T> - т.е.

var result = db.ExecuteQuery<YourType>(@"your query here with {0}, {1} etc",
                 arg0, arg1, ...);

2: напишите, что TSQL udf отображается в контексте данных:

var result = db.YourUdf(arg0, ...);

Оба действительны и будут работать с LINQ-to-SQL;лично я предпочитаю подход first , но подход UDF позволяет более повторно использовать его на уровне DB, за счет более сложного развертывания (т.е. уровня приложений и уровня базы данных одновременно).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...