Есть ли другой способ сделать этот запрос?(содержит разделенную строку в запросе linq-to-sql) - PullRequest
1 голос
/ 06 июля 2011

У меня есть база данных sql с таблицей, содержащей несколько продуктов, каждый продукт может быть произведен на одной или нескольких машинах.Теперь я хочу найти все продукты, которые производятся на определенной машине. Таблица

выглядит следующим образом:

productreference (nvarchar) |машины (nvarchar)

P1 |1,2,3

P2 |2

P3 |2

P4 |2,3

Я попытался использовать следующий запрос, но обнаружил, что linq-to-sql не поддерживает разделенную строку.

    public List<string> GetReferenceForMach(string machName)
    {
        IEnumerable<string> producttmp = from product in productInfo
                                         let machines = product.Machines.Split(',')
                                         from machine in machines
                                         where machine == machName
                                         select product.Reference;

        return producttmp.ToList(); 
    }

Есть ли другой способ программированияэто?

Ответы [ 4 ]

3 голосов
/ 06 июля 2011

Когда жизнь дает вам строки в базе данных, нормальным ответом является использование анализа строки:

string machName;

string midName = ',' + machName + ',';

from product in productInfo
where (',' + product.Machines + ',').Contains(midName)
select product.Reference

Нет индексации, чтобы помочь этому запросу - так что приготовьтесь к сканированию таблицы.

1 голос
/ 06 июля 2011

Linq to SQL - хорошо , но не магия ! Тем не менее, он должен сократить ваш запрос до исполняемого SQL (именно поэтому такие функции, как string.Split, запрещены - они затрудняют генерацию эквивалентного SQL). В этом случае вы запрашиваете что-то, что просто не может быть сделано сервером SQL (поиск по содержимому поля, разделенного запятыми).

Если вы хотите, чтобы это работало так, как я думаю, вы ожидаете, то вам нужно изменить схему базы данных так, чтобы Machines имела свою собственную таблицу и могла эффективно индексироваться и запрашиваться.

В качестве альтернативы вы можете получить всю таблицу / набор результатов, используя Linq to SQL, а затем использовать старый добрый Linq to Objects для выполнения тяжелой работы:

IEnumerable<string> producttmp = from product in productInfo.AsEnumerable()
                                 let machines = product.Machines.Split(',')
                                 from machine in machines
                                 where machine == machName
                                 select product.Reference;

(не проверено)

0 голосов
/ 07 июля 2011

Спасибо всем за помощь,

Теперь работает, я использовал следующий код:

        IEnumerable<string> producttmp = from product in productInfo
                                         let midName = "," + machName + ","
                                         let checkMachines = "," + product.Machines + ","
                                         where (checkMachines.IndexOf(midName) > -1)
                                         select product.Reference;

        return producttmp.ToList(); 
0 голосов
/ 06 июля 2011

Try

return productInfo.AsEnumerable()
                  .Where(p => p.Machines.Split(',').Contains(machName))
                  .Select(p => p.Reference)
                  .ToList()

AsEnumerable () обрушивает всю таблицу и сокращает запрос до linq-to-objects.Недостатком этого метода, очевидно, является то, что он может быть очень неэффективным, если у вас огромный стол.

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