Как запросить несколько таблиц с использованием синтаксиса LINQ в. NET core 3 - PullRequest
2 голосов
/ 17 июня 2020

Мне нужно запросить две таблицы базы данных для поискового запроса и вернуть результаты. В EF Core 2 работало следующее:

var SearchTerm = "hello";
IQueryable<TableA> q;
q = (from a in context.TableA
     join b in context.TableB on a equals b.A into leftjoin
     from c in leftjoin.DefaultIfEmpty()                     
     where c.Column1.Contains(SearchTerm)
        || a.Column1.Contains(SearchTerm)
        || a.Column2.Contains(SearchTerm)
     select a);

return q.Include(a => a.TableD)
        .GroupBy(a => a.Id)
        .Select(group => group.First())
        .ToList();

Идея вышеизложенного заключается в том, чтобы взять SearchTerm и запросить два столбца из TableA, присоединиться к TableB, а также запросить столбец в этом, а затем выбрать отдельные значения из таблицы A.

In. NET 3, приведенное выше вызывает ошибку, говоря, что он не может быть преобразован в SQL. Я попытался переписать это, лучшее, что я могу сделать, это следующее:

var SearchTerm = "hello";
var q = (from a in context.TableA
         join b in context.TableB on a equals b.A into leftjoin
         from c in leftjoin.DefaultIfEmpty()                     
         where c.Column1.Contains(SearchTerm)
             || a.Column1.Contains(SearchTerm)
             || a.Column2.Contains(SearchTerm)                    
         select a.Id).Distinct().ToList();  

return context.TableA
    .Where(a => q.Contains(a.Id))
    .Include(c => c.TableD)
    .ToList();

Что работает нормально, но включает два запроса к базе данных, так как у меня уже есть список TableA из первого запроса, было бы здорово иметь возможность просто использовать это, не извлекая идентификаторы и не выполняя второй запрос. Также было бы предпочтительно убедиться, что база данных продолжает обрабатывать отдельную часть, а не C#.

Определения A и B:

public class TableA
{
    public int Id { get; set; }

    public string Column1 { get; set; }

    public string Column2 { get; set; }

    public int TableDId { get; set; }

    public TableD TableD { get; set; }
}

public class TableB
{
    public int Id { get; set; }

    public string Column1 { get; set; }

    public int TableAId { get; set; }

    public TableA TableA { get; set; }
}

1 Ответ

1 голос
/ 17 июня 2020

Если я вас правильно понял, у вас есть отношение «один ко многим» между TableA и TableB, поэтому должна быть возможность добавить свойство навигации по коллекции в TableA, как в в этом руководстве для пример:

public class TableA
{
    public int Id { get; set; }
    ...
    public ICollection<TableB> TableBs { get; set; } 
}

Итак, вы можете попробовать сделать что-то вроде этого:

context.TableA
    .Where(ta => ta.TableBs.Any(tb => tb.Column1.Contains(SearchTerm)) 
        || ta.Column1.Contains(SearchTerm) 
        || ta.Column2.Contains(SearchTerm))
    .Include(c => c.TableD)
    .ToList();

Другой вариант - попробовать подзапрос:

var q = (from a in context.TableA
         join b in context.TableB on a.Id equals b.TableAId  into leftjoin
         from c in leftjoin.DefaultIfEmpty()                     
         where c.Column1.Contains(SearchTerm)
             || a.Column1.Contains(SearchTerm)
             || a.Column2.Contains(SearchTerm)                    
         select a.Id);  // remove Distinct and ToList

return context.TableA
    .Where(a => q.Contains(a.Id))
    .Include(c => c.TableD)
    .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...