Skip to content

Latest commit

 

History

History
83 lines (71 loc) · 5.49 KB

File metadata and controls

83 lines (71 loc) · 5.49 KB

← EF Core

Запросы в EF Core

Пример простого запроса для чтения данных с соединением двух таблиц:

return (from f in _context.Firms
             join cr in _context.CatalogRubrics on f.RubricId equals cr.RubricId
             where cr.UrlMask == rubric
                   && f.IsAllowed
             orderby f.Rank descending
             select f).Take(N).AsNoTracking().ToList();

Соединние таблиц выполняется аналогично SQL: join cr in _context.CatalogRubrics on f.RubricId equals cr.RubricId. Первые N строк выбираются оператором Take(N) (в SQL это top(N)). AsNoTracking() указывает, что для запроса для чтения данных надо отключить отслеживание изменений.
select f - вернет данные только из одной таблицы f. Чтобы вернуть необходимые данные из обеих таблиц, надо сделать класс, который совмещает данные из этих таблиц, или, анонимно new { f, cr }.

📘 Сложные операторы запросов
Запросы в Entity Framework Core (entityframeworktutorial.net)
Linq-to-Entities Query (entityframeworktutorial.net)

EF Core GROUP BY

Пример запроса, когда используются несколько полей и создается объект заданного типа:

SELECT        City, UrlMask, ISO2
FROM          CatalogRubricCities
GROUP BY City, UrlMask, ISO2

private IQueryable<City> RubricCityQuery()
{
    return _context.CatalogRubricCities
           .GroupBy(o => new { o.City, o.UrlMask, o.Iso2})
           .Select(g => new City {Name = g.Key.City, UrlMask = g.Key.UrlMask, CountryCode = g.Key.Iso2});
}

//где то в программе вызов, например такой:
 cities = await RubricCityQuery().AsNoTracking().ToListAsync();

📘 Преобразование оператора LINQ GroupBy
📘 Сложные операторы запросов: GroupBy
Grouping and Aggregating Data with LINQ
📘 Группировка элементов последовательности

Еще вариант группировки с условием, подсчетом общего количества в группе и сортировкой по имени

public IList<City> GetFirmCities(List<OfficeCard> offices, out bool hasMore)
        {
            hasMore = (from o in offices where o.CityId == null select o).FirstOrDefault() != null;
            return (from o in offices
                    where o.CityId != null
                    group o by (o.City, o.CityId) into g
                    select new City { Name = g.Key.City, Id = (int)g.Key.CityId, Count=g.Count() })
                   .OrderBy(g => g.Name).ToList();

           
//Другой вариант:
            //return offices
            //    .Where(o=> o.CityId != null)
            //    .GroupBy(o => new { o.City, o.CityId})
            //    .Select(g => new City {Name = g.Key.City, Id =(int)g.Key.CityId})
            //    .OrderBy(g => g.Name)
            //    .ToList();
        }

EF Core LEFT OUTER JOIN

Когда есть основная таблица, а для некоторых записей есть сведения в связанной таблице. Но нам нужны данные для основной таблицы, даже если нет уточнений. Для этого в SQL используется оператор LEFT OUTER JOIN (левое соединение), который берет все данные из основной таблицы.
Можно использовать into:

SELECT        f.*,fe.*
FROM          Firms AS f LEFT OUTER JOIN
                         TFirmExtensions AS fe ON f.FirmId = fe.FirmId

var q= from f in _context.Firms
       join fe in _context.TfirmExtensions on f.FirmId equals fe.FirmId
       into Details 
       from d in Details.DefaultIfEmpty()
       select new { f, d};

📘 Левое соединение
EntityFramework: левое (внешнее) соединение в Linq (stackoverflow.com)
📘 Селектор коллекции ссылается на внешний источник в предложении WHERE
📘 Выполнение левых внешних соединений