Как сделать подзапрос в LINQ?

docs описывают атрибуты, доступные в запросе. В большинстве случаев request.data будет пустым, потому что он используется как резерв:

request.data Содержит входящие данные запроса как строку, если он пришел с типом mimetype Flask не обрабатывается.

  • request.args: пары ключ / значение в строке запроса URL
  • request.form: пары ключ / значение в теле, из HTML почтовая форма или запрос JavaScript, который не закодирован JSON
  • request.files: файлы в теле, которые Flask хранятся отдельно от form. HTML-формы должны использовать enctype=multipart/form-data или файлы не будут загружены.
  • request.values: объединены args и form, предпочитая args, если клавиши перекрываются

Все это MultiDict экземпляры. Вы можете получить доступ к значениям, используя:

  • request.form['name']: используйте индексирование, если знаете ключ существует
  • request.form.get('name'): используйте get, если ключ может отсутствовать
  • request.form.getlist('name'): используйте getlist, если ключ отправляется несколько раз и вам нужен список значений. get возвращает только первое значение.

67
задан Jon Schneider 10 April 2018 в 14:12
поделиться

6 ответов

Вот подзапрос для Вас!

List<int> IdsToFind = new List<int>() {2, 3, 4};

db.Users
.Where(u => SqlMethods.Like(u.LastName, "%fra%"))
.Where(u =>
    db.CompanyRolesToUsers
    .Where(crtu => IdsToFind.Contains(crtu.CompanyRoleId))
    .Select(crtu =>  crtu.UserId)
    .Contains(u.Id)
)
<час>

Относительно этой части вопроса:

predicateAnd = predicateAnd.And(c => c.LastName.Contains(
                                TextBoxLastName.Text.Trim()));

я настоятельно рекомендую извлечь строку из текстового поля прежде, чем создать запрос.

string searchString = TextBoxLastName.Text.Trim();
predicateAnd = predicateAnd.And(c => c.LastName.Contains( searchString));

Вы хотите обеспечить хороший контроль над тем, что отправляется в базу данных. В исходном коде одно возможное чтение состоит в том, что необрезанная строка отправляется в базу данных за обрезкой - который не является хорошей работой для базы данных для выполнения.

77
ответ дан Pure.Krome 24 November 2019 в 14:40
поделиться

Нет никакого подзапроса, необходимого с этим оператором, который лучше записан как

select u.* 
from Users u, CompanyRolesToUsers c
where u.Id = c.UserId        --join just specified here, perfectly fine
and u.lastname like '%fra%'
and c.CompanyRoleId in (2,3,4)

или

select u.* 
from Users u inner join CompanyRolesToUsers c
             on u.Id = c.UserId    --explicit "join" statement, no diff from above, just preference
where u.lastname like '%fra%'
  and c.CompanyRoleId in (2,3,4)

Однако в LINQ, которым это было бы

from u in Users
from c in CompanyRolesToUsers 
where u.Id == c.UserId &&
      u.LastName.Contains("fra") &&
      selectedRoles.Contains(c.CompanyRoleId)
select u

или

from u in Users
join c in CompanyRolesToUsers 
       on u.Id equals c.UserId
where u.LastName.Contains("fra") &&
      selectedRoles.Contains(c.CompanyRoleId)
select u

, Который снова, оба респектабельные способы представить это. Я предпочитаю явный синтаксис "соединения" в обоих случаях сам, но там это...

22
ответ дан TheSoftwareJedi 24 November 2019 в 14:40
поделиться

Это - то, как я делал подзапросы в LINQ, я думаю, что это должно получить то, что Вы хотите. Можно заменить явный CompanyRoleId == 2... с другим подзапросом для различных ролей, Вы хотите или присоединяетесь к нему также.

from u in Users
join c in (
    from crt in CompanyRolesToUsers
    where CompanyRoleId == 2
    || CompanyRoleId == 3
    || CompanyRoleId == 4) on u.UserId equals c.UserId
where u.lastname.Contains("fra")
select u;
6
ответ дан Noah 24 November 2019 в 14:40
поделиться

Вы могли сделать что-то вроде этого для своего случая - (синтаксис может быть немного выключен). Также посмотрите на этот ссылка

subQuery = (from crtu in CompanyRolesToUsers where crtu.RoleId==2 || crtu.RoleId==3 select crtu.UserId).ToArrayList();

finalQuery = from u in Users where u.LastName.Contains('fra')  && subQuery.Contains(u.Id) select u;
2
ответ дан Perpetualcoder 24 November 2019 в 14:40
поделиться

Хорошо, вот основной запрос соединения, который получает корректные записи:

   int[] selectedRolesArr = GetSelectedRoles();
    if( selectedRolesArr != null && selectedRolesArr.Length > 0 ) 
    {

    //this join version requires the use of distinct to prevent muliple records
        //being returned for users with more than one company role.
    IQueryable retVal = (from u in context.Users
                        join c in context.CompanyRolesToUsers
                          on u.Id equals c.UserId
                        where u.LastName.Contains( "fra" ) &&
                            selectedRolesArr.Contains( c.CompanyRoleId )
                        select  u).Distinct();
}

, Но вот код, который наиболее легко интегрируется с алгоритмом, который мы уже имели в распоряжении:

int[] selectedRolesArr = GetSelectedRoles(); 
if ( useAnd ) 
       { 
          predicateAnd = predicateAnd.And( u => (from c in context.CompanyRolesToUsers 
                       where selectedRolesArr.Contains(c.CompanyRoleId) 
                       select c.UserId).Contains(u.Id)); 
        } 
        else 
        { 
           predicateOr = predicateOr.Or( u => (from c in context.CompanyRolesToUsers 
                          where selectedRolesArr.Contains(c.CompanyRoleId) 
                         select c.UserId).Contains(u.Id) ); 
        } 

, который является благодаря плакату в форум LINQtoSQL

2
ответ дан marcel_g 24 November 2019 в 14:40
поделиться

Вот версия SQL, который возвращает корректные записи:

select distinct u.* 
from Users u, CompanyRolesToUsers c
where u.Id = c.UserId        --join just specified here, perfectly fine
and u.firstname like '%amy%'
and c.CompanyRoleId in (2,3,4)

кроме того, обратите внимание, что (2,3,4) список, выбранный из списка флажка пользователя веб-приложения, и я забыл упоминать что я просто hardcoded это для простоты. Действительно это - массив значений CompanyRoleId, таким образом, это могло быть (1) или (2,5) или (1,2,3,4,6,7,99).

Также другая вещь, которую я должен определить более ясно, состоит в том, что PredicateExtensions используются для динамичного добавления пунктов предиката к, Где для запроса, в зависимости от которых полей формы пользователь веб-приложения заполнил. Таким образом, хитрая часть для меня - то, как преобразовать рабочий запрос в Выражение LINQ, которое я могу присоединить к динамическому списку выражений.

я дам некоторые демонстрационные запросы LINQ выстрел и видеть, могу ли я интегрировать их с нашим кодом, и затем добираться отправляют мои результаты. Спасибо!

marcel

1
ответ дан marcel_g 24 November 2019 в 14:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: