Результаты сортировки выходных данных отличаются от оператора SQL против LINQ до SQL - PullRequest
2 голосов
/ 13 марта 2020

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

CREATE TABLE MyTable (    
   KEY_CODE varchar(5)
);

insert into MyTable(KEY_CODE) values('00');
insert into MyTable(KEY_CODE) values('-01');
insert into MyTable(KEY_CODE) values('01');
insert into MyTable(KEY_CODE) values('02');
insert into MyTable(KEY_CODE) values('03');
insert into MyTable(KEY_CODE) values('T');

Затем я запрашиваю все мои элементы KEY_CODE и сортирую их по KEY_CODE AS C

select * from MyTable 
order by KEY_CODE

И вот результат вывода в MS SQL Студия управления сервером. Вы можете видеть, что MS SSMS понимает, что ключ "-01" меньше, чем "00" и "01".

enter image description here

Теперь в моем VB . NET проект, у меня также есть таблица данных с тем же столбцом и данными. Но порядок столбца KEY_CODE не совпадает с тем из MS SSMS. Вы можете увидеть таблицу выходных данных в режиме отладки, о которой я упомянул на снимке ниже. Клавиша «-01» находится не в верхней части результата.

Я ожидаю, что результат порядка от LINQ до SQL должен быть таким же, как и у MS SSMS. Как мне этого добиться?

Dim myTable As DataTable = New DataTable("MyTable")
Dim col As DataColumn = New DataColumn("KEY_CODE")
col.DataType = System.Type.GetType("System.String")

myTable.Columns.Add(col)

Dim row1 As DataRow = myTable.NewRow()
Dim row2 As DataRow = myTable.NewRow()
Dim row3 As DataRow = myTable.NewRow()
Dim row4 As DataRow = myTable.NewRow()
Dim row5 As DataRow = myTable.NewRow()
Dim row6 As DataRow = myTable.NewRow()

row1.Item("KEY_CODE") = "00"
row2.Item("KEY_CODE") = "-01"
row3.Item("KEY_CODE") = "01"
row4.Item("KEY_CODE") = "02"
row5.Item("KEY_CODE") = "03"
row6.Item("KEY_CODE") = "T"

myTable.Rows.Add(row1)
myTable.Rows.Add(row2)
myTable.Rows.Add(row3)
myTable.Rows.Add(row4)
myTable.Rows.Add(row5)
myTable.Rows.Add(row6)

Dim datarows As DataRow() = myTable.Select()
Dim output = (From row In datarows
              Order By "KEY_CODE ASC"
              Select row Distinct).CopyToDataTable()

enter image description here

1 Ответ

0 голосов
/ 15 марта 2020

Для LINQ по SQL есть много онлайн-учебников, но это НЕ ВСТАВЛЯЕТ синтаксис SQL в виде строки в запрос LINQ. Вместо этого вы пишете код в том, что кажется правильным VB. NET кодом, со строгой проверкой типов и помощью автозаполнения, но он преобразуется в оператор SQL, фактически не выполняя ваш код, а вместо этого анализируя выражение деревья и используя отражение, чтобы попытаться увидеть, что вы хотите из базы данных и генерирует оператор SQL, чтобы получить его. Поскольку он преобразован и запущен на ядре базы данных, он имеет некоторые тонкие различия, например, типы, допускающие значения NULL, действующие немного по-разному в SQL, чем в Visual Basi c, и вы получаете поведение SQL.

Запрос, подобный следующему:

   From Item in new DataContext().Items 
   WHERE Item.Key_Code>0
   Order By Item.KEY_CODE 
   SELECT KeyCode=Item.KEY_CODE, Member=Item.Member

сгенерирует SQL, что почти отражает этот запрос. Чего он не сделает, так это перенесет всю таблицу «Предметы» в память и выполнит «где», «упорядочить по» или «Выбрать» в Visual Basi c.

Ваш код с

Dim output = (From row In datarows
              Order By "KEY_CODE ASC"
              Select row Distinct).CopyToDataTable()

начинается с объекта памяти (datarow), а не контекста данных, поэтому LINQ будет выполнен в Visual Basi c, который обладает гораздо большей мощностью, чем LINQ TO SQL. Он постоянно сравнивает «KEY_CODE AS C» как строку для каждой строки и, поскольку все результаты совпадают, он не может изменить порядок.

Измените его на что-то вроде этого:

Dim output = (From row In MyTable.Rows.Cast(of DataRow)
              Order By row.item("KEY_CODE")
              Select row Distinct).CopyToDataTable()

или

Dim output = (From row as DataRow In MyTable
                  Order By row.item("KEY_CODE")
                  Select row Distinct).CopyToDataTable()

Кстати, есть несколько способов обработки данных в выражениях LINQ, но из-за того, что Коллекции DataRow существовали до появления LINQ, это немного странно, поэтому я показал два альтернативных способа выполнения запросов LINQ к DataTable.

...