Попытка получить динамический порядок c по предложению в Linq to Entities - PullRequest
0 голосов
/ 04 мая 2020

Я пытаюсь получить динамический порядок c по предложению, но не могу понять синтаксис. Я подумал, что я взломал его с помощью встроенных операторов if, но они не поддерживаются в EF.

Пользователь сможет выбрать поле для сортировки (первоначально по возрастанию), вероятно, щелкнув заголовок dgv.

Это мой код: -

Dim q = (From customer In db.tblcustomers.Where(Function(x) CBool(x.f_rn >= 0 And x.cu_brn = "00" _
    And (txtFiltAccno.Text.Trim = "" Or x.cu_accno.ToUpper.Contains(txtFiltAccno.Text.ToUpper.Trim)) _
    And (txtFiltCustName.Text.Trim = "" Or       x.cu_name.ToUpper.Contains(txtFiltCustName.Text.ToUpper.Trim)) _
    And (txtFiltPhone.Text.Trim = "" Or x.cu_telno.ToUpper.Contains(txtFiltPhone.Text.ToUpper.Trim)) _
    And (txtFiltFax.Text.Trim = "" Or x.cu_faxno.ToUpper.Contains(txtFiltFax.Text.ToUpper.Trim)) _
    And (txtFiltEmail.Text.Trim = "" Or x.cu_email.ToUpper.Contains(txtFiltEmail.Text.ToUpper.Trim))))
    select customer.f_rn, customer.cu_accno, customer.cu_name, customer.cu_add1, customer.cu_add2,     customer.cu_add3, customer.cu_add4, customer.cu_add5,
            customer.cu_telno, customer.cu_faxno, customer.cu_email).OrderBy(Function(u) 
IIf(a = "cu_name", u.cu_name,
IIf(a = "cu_add1", u.cu_add1,
IIf(a = "cu_add2", u.cu_add2,
IIf(a = "cu_add3", u.cu_add3,
IIf(a = "cu_add4", u.cu_add4,
IIf(a = "cu_add5", u.cu_add5,
IIf(a = "cu_telno", u.cu_telno,
IIf(a = "cu_faxno", u.cu_faxno,
IIf(a = "cu_email", u.cu_email, u.cu_accno)))))))))).Skip((pagenum - 1) * 25).Take(25)

1 Ответ

1 голос
/ 04 мая 2020

Ooof. Это может оказаться довольно неприятным и, вероятно, медленным SQL. Прочитайте https://use-the-index-luke.com/sql/where-clause/obfuscation/smart-logic (не тот блог, на который я хотел бы сослаться - но я не могу найти тот, о котором я думаю, он выглядел гораздо более старым, как когда-то a us enet post)

Запросы в LINQ являются кумулятивными, и они запускаются только тогда, когда что-то перечисляет результат, например, вызывает ToArray для него или ForEach его. Это означает, что вы можете построить свой запрос динамически за несколько шагов. (Я немного озвучил некоторые вещи для ясности / чтобы проиллюстрировать точку здесь; я не использовал ваши настоящие имена столбцов):

Dim q as IEnumerable(Of Customer) = db.Customers

If nameTextBox.Text <> "" Then q = q.Where(Function(x) x.Name = nameTextBox.Text)

If ageTextBox.Text <> "" Then q = q.Where(Function(x) x.Age = ageTextBox.Text)

If jobTextBox.Text <> "" Then q = q.Where(Function(x) x.Age = jobTextBox.Text)

If sortByCombo.SelectedValue = "Name" Then q = q.OrderBy(Function(x) x.Name)
Else If ....

Если вы только что-то положили в поле Name, q имеет один Where, вызванный на него. Если вы поместите что-то во все 3 поля, Where будут кумулятивными и будут действовать как единое целое с условиями ANDed в SQL. Запрос БД не выполняется ни в одном из пунктов выше, даже если вы добавили OrderBy. Если вы хотите больше информации об этом, посмотрите «LINQ отложенное выполнение». В тот момент, когда вы попытаетесь прочитать результат, запрос будет запущен.

пс; Я не уверен, что БД будет выполнять упорядочение, требуя повторного запроса при каждом изменении порядка - возможно, просто загрузите результаты в элемент управления, который знает, как сортировать (большинство элементов управления сеткой, windows и веб знать, как кэшировать и сортировать свои данные, чтобы избежать передачи туда и обратно, или использовать контейнер на стороне клиента, который может обрабатывать сортировку, например, DataTable, SortedList et c

...