Entity framework сортировка по дате

Обновлено: 05.07.2024

Назначение протокола OData — выполнение запросов от внешних приложений к серверу баз данных Creatio.

Приложение Creatio поддерживает протоколы OData 4 и OData 3. OData 4 предоставляет больше возможностей, чем OData 3. Основное отличие протоколов — ответ на запрос, возвращаемый сервером, имеет разный формат данных. Различия протоколов OData 3 и OData 4 описаны в официальной документации OData. При планировании интеграции с Creatio по протоколу OData необходимо использовать протокол версии 4.

Протокол OData 4

Доступ к объектам Creatio по протоколу OData 4 предоставляет веб-сервис odata .

Протокол OData 3

Доступ к объектам Creatio по протоколу OData 3 предоставляет веб-сервис EntityDataService.svc .

Сервис EntityDataService.svc предоставляет возможность работы с объектами Creatio в WCF-клиенте.

Организация работы WCF-клиента реализована путем получения метаданных сервиса и создания клиентских прокси-классов. Клиентское приложение будет использовать эти классы-посредники для работы с сервисом EntityDataService.svc Creatio.

Чтобы реализовать клиентское приложение:

Способы генерации прокси-классов сервиса EntityDataService.svc :

  • C использованием утилиты DataServiceModel Metadata Utility Tool (DataSvcutil.exe) .
  • Из проекта клиентского приложения Visual Studio.

Генерация прокси-классов с использованием утилиты DataServiceModel Metadata Utility Tool

  • WSDL — документ метаданных службы. Описывает модель данных, предоставленную службой данных.
  • CSDL — файл модели данных. Используется язык определения концептуальной схемы ( CSDL ), описанный в спецификации [MC–CSDL]: формат файла определения концептуальной схемы.
  • EDMX — *.xml-файл. Создается с помощью программ для работы с моделью EDM , входящих в комплект Entity Framework . Дополнительные сведения описаны в спецификации [MC–EDMX]: модели EDM для формата упаковки служб данных.

Детальная информация по утилите DataSvcutil.exe приведена в официальной документации MSDN.

Генерация прокси-классов из проекта клиентского приложения Visual Studio

Чтобы сгенерировать прокси-классы из проекта клиентского приложения Visual Studio:

  1. Щелкните правой клавишей мыши по проекту, в котором планируется реализация интеграции с Creatio, и выберите в контекстном меню пункт Add Service Reference… .
  2. В поле Address введите полный адрес сервиса EntityDataService.svc .
  3. Нажмите на кнопку Go и укажите имя и пароль пользователя Creatio. Если аутентификация прошла успешно, то в окне Services отобразятся поддерживаемые сервисом сущности.
  4. В поле Namespace укажите имя пространства имен, в котором будут расположены сгенерированные прокси-классы. Например, CreatioServiceReference . Ссылку на это пространство имен в дальнейшем необходимо добавить в блок using кода проекта.
  5. Для генерации прокси-классов нажмите кнопку ОК . При этом в проект будет добавлен новый файл кода Reference.cs , содержащий описание прокси-классов, которые теперь могут использоваться для обращения и взаимодействия с ресурсами сервиса данных как с объектами.

В Visual Studio также есть возможность генерировать прокси-классы сервиса из сохраненного на диске файла метаданных сервиса. Для этого на шаге 2 в поле Address необходимо ввести полный путь к файлу метаданных с префиксом file:// .

Для успешной компиляции в код проекта необходимо добавить директивы using и объявление переменной адреса сервиса OData.

В предыдущем уроке мы реализовали страницы для совершения CRUD-операций для сущностей Student. В этом уроке мы добавим сортировку, фильтрацию и разбиение по страницам, а также создадим страницу, на которой будет простая группировка.

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

image

Добавление заголовков-сортировщиков в столбцы на странице Students Index

Для добавления сортировки вам нужно изменить метод Index контроллера Student и добавить код на представление Student Index.

Добавление сортировки в метод Index

В Controllers\StudentController.cs замените метод Index на следующий код:

При первом вызове страницы Index строки запроса нет, и студенты отображаются в порядке по возрастанию LastName, что указано как вариант по умолчанию в switch. После того, как пользователь щелкает на заголовке столбца, соответствующее значение sortOrder добавляется в строку запроса.

The two ViewBag variables are used so that the view can configure the column heading hyperlinks with the appropriate query string values:


Это тернарное утверждения. Первое утверждает, что, если sortOrder равен null или пустой, то значение ViewBag.NameSortParam устанавливается в “Name desc”, иначе устанавливается в пустую строку.

  • Если сортируется по возрастанию по LastName, ссылка LastName должна указывать на сортировку по убыванию по LastName и ссылка EnrollmentDate на сортировку по возрастанию по Date соответственно.
  • Если сортируется по убыванию по LastName, ссылки должны указывать на сортировку по возрастанию как по LastName так и по Date.
  • Если сортируется по возрастанию по Date, ссылки должны указывать на сортировку по возрастанию по LastName и по убыванию по Date.
  • Если сортируется по убыванию по Date, ссылки должны указывать на сортировку по возрастанию по LastName и по возрастанию по Date.

Добавление заголовков-ссылок в Student Index

В Views\Student\Index.cshtml замените код контейнеров<tr> и<th> следующим:


В этом коде используется информация в свойствах ViewBag для заполнения ссылок подходящими значениями запроса. Запустите проект и щёлкните на заголовках, чтобы убедиться, что сортировка работает.

image

Добавление поиска

Чтобы добавить фильтрацию, вы должны добавить на представление текстовое поле и кнопку отправки и сделать соответствующие изменения в коде метода Index.

Изменение кода метода Index

В Controllers\StudentController.cs замените код метода Index


Мы добавили в метод Index параметр searchString, кляузу в LINQ-утверждение, с помощью которого выбираются только те студенты, имя или фамилия которых содержит строку поиска. Строка поиска получается из текстового поля, которое вы позже добавите на представление. Код, который добавляет кляузу where в запрос, выполняется только в том случае, если задано значение для поиска:

Добавление поиска на представление

В Views\Student\Index.cshtmlпрямо перед открывающим тегом table добавьте заголовок, текстовое поле и кнопку Search:


Запустите проект, введите что-нибудь в строку поиска и нажмите на кнопку Search чтобы убедиться в работе фильтрации.

image

Добавление разбиения по страницам

Для этого необходимо сначала установить NuGet-пакет PagedList, затем сделать изменения в методе Index и добавить на представление ссылки на страницы.

image

Установка NuGet-пакета NuGet Package

NuGet-пакет PagedList устанавливает тип коллекции PagedList. Когда вы добавляете в коллекцию этого типа результаты запроса, вам предоставляется набор свойств и методов для обеспечения разбиения результатов по страницам.

В Visual Studio выберите проект. Затем нажмите в меню Tools пунктLibrary Package Manager и потом Add Library Package Reference.

В Add Library Package Reference нажмите на вкладку Online слева и введите в строку поиска "pagedlist". Как только появится пакет PagedList нажмите Install.

image

Добавление функциональности разбиения по страницам в метод Index

В Controllers\StudentController.cs добавьте using PagedList:

Замените код метода Index:


Добавлен параметр page, несущий информацию о параметре, по которому в данный момент производится сортировка, и параметр в сигнатуре метода:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)

При первом вызове страницы (или если пользователь не нажал на одну из ссылок на страницы), переменная page равна null. После нажатия в эту переменную помещается номер страницы.

Свойство ViewBag передаёт в представление текущий параметр сортировки для её сохранения при переходе на другие страницы:

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


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


В метод ToPagedList передаётся значение индекса страницы, которое равно 0, в отличие от номера страницы, который равен 1. Поэтому код извлекает 1 из номера страницы, чтобы получить значения индекса страницы (два знака вопроса обозначают оператор, определяющий значение по умолчанию для типа nullable, таким образом, выражение (page ?? 1) возвращает значение page в том случае, если оно имеет значение, или 1, если page равен null. Другими словами, установите pageIndex в page — 1 если page не равен null, или установите его в 1-1 если он равен null)

Добавление ссылок на страницы на представление

В Views\Student\Index.cshtml замените исходный код на:


Утверждение @model показывает, что представление принимает на вход объект типа PagedList вместо объекта типа List.

Текстовая строка инициализируется текущей строкой поиска чтобы пользователь мог переходить со страницы на страницу не теряя строку поиска:

Find by name: Html.TextBox("SearchString", ViewBag.CurrentFilter as string) &nbsp;

Ссылки в заголовках столбцов используют строку запроса для передачи текущей строки поиска в контроллер, чтобы пользователь мог сортировать возвращённые механизмом фильтра результаты:

В «подвале» страницы находится запись, демонстрирующая номер страницы и ссылки навигации:

Page [current page number] of [total number of pages] << < Prev Next > >>

<< — ссылка на первую страницу, <Prev – ссылка на предыдущую страницу, и так далее. Если пользователь находится на странице с номером 1, ссылки на предыдущие страницы недоступны, и также для последней страницы. Каждая ссылка на страницу передаёт номер выбранной страницы и текущие данные о фильтрации и сортировки в контроллер в строке запроса, таким образом позволяя управлять этими данными в процессе разбиения на страницы.

Если результатов нет, показывается надпись "Page 0 of 0".

image

Щелкните ссылки на страницы в различных режимах сортировки и введите какую-либо строку поиска, чтобы убедиться, что всё работает в связке.

Создание страницы со статистикой

  • Создать класс с моделью представления для данных, которые мы будем передавать в представление
  • Изменить код метода About в контроллере Home.
  • Изменить код представления About.

Создание модели представления

Создайте папку ViewModels и в ней создайте файл EnrollmentDateGroup.cs со следующим содержанием:

Изменение контроллера Home

В HomeController.cs добавьте необходимые using:


Добавьте переменную с контекстом базы данных:

private SchoolContext db = new SchoolContext();

Замените код метода About на:


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

Оба класса запрашиваются из базы данных посредством entity framework.
А класс Container содержится во многих других классах, которые, в свою очередь, тоже запрашиваются из базы данных. Проблема в том, что мне необходимо обеспечить сортировку списка Parameters внутри Container абсолютно во всех классах, которые этот Container содержат. Скорее всего, каким-то образом список параметров должен сортироваться уже на стадии запроса из базы данных (хотя, если я ошибаюсь, исправьте).
Возможно надо прописать что-то в конфигурации?

Или прописать в dbSet в Dao, но тогда ведь другие классы как-то запрашивают Container в обход Dao .

Различная сортировка при получении данных из БД Oracle
база данных оракл (понятия не имею какая версия. Развернута на unix подобной системе). В ней есть.


Ошибка при получении данных из БД при использовании MVC framework 4.0
// HomeControlers.cs using System; using System.Collections.Generic; using System.Linq; using.

Трудности при получении данных
В справочнике ВидМатериала находятся реквизиты Наименование, ПлотностьСырья и т.д. Процедура.

Якобинец, в коде, сгенерированном Entity, есть запросы к бд. находите их и дописывайте order by. Расскажи немного подробнее
Согласно StackOverflow, сортировка во время запроса невозможна. Надо сначала получить результат, а только потом упорядочивать данные. Но может быть, я что-то не знаю .

Давайте я на всякий случай напишу своё решение.
Если кто-нибудь знает лучший вариант - поделитесь.

Напомню, в чём принципиальная проблема: класс Container содержится во многих классах, в том числе в глубоко вложенном виде. Мы запрашиваем эти классы через разные запросы и разные DAO. И в каждом случае список Parameters в классе Container должен быть отсортирован по полю Parameter.Name

Вариант с сортировкой в Dao, как я предполагаю, не подходит нам по следующим причинам:

1 - указать приход отсортированных значений невозможно. Надо сначала сделать запрос, а только потом сортировать. Это значит, что мы должны изменить все функции запросов наподобие GetByFactor1, GetByFactor2, GetByMonth - реализовать сортировку полученных данных в каждой из функций каждого класса;

2 - как я уже говорил, Container содержится во многих местах и часто глубоко вложен. Если нам будет необходим Container внутри ещё одного класса, который будет запрашиваться через свой DAO, нам также будет необходимо определить логику сортировки там;

3 - если мы решим вызывать один DAO из другого, снова будет проблема переопределения сортировки в каждом из методов GetByMonth, ByDate и т.д., да и дружить запросы с вызовами функций проблематично.
Потому необходимо работать не с Dao, а с моделью.

И тут перед нами два выхода:
Первый и самый очевидный заключается в настройке свойства. Но проблема заключается в том, что EntityFramework не кладёт сразу же весь список в соответствующее свойство, а добавляет в него данные предположительно через Add. Потому приходится определять не setter, а getter.

То есть каждый раз, когда Framework хочет положить новый элемент, мы предварительно сортируем коллекцию, в которую добавляется новый элемент. А так как на стадии запроса данных EntityFramework обращается к нему раз десять, каждый раз перед передачей для добавления нового элемента будет проходить сортировка, что не правильно с точки зрения производительности.

Отсюда вариант, который я хочу предложить: добавить в IEntity метод Prepare

В предыдущей статье мы рассмотрели как создаются LINQ-запросы в Entity Framework. В этой и последующих статьях мы рассмотрим операции CRUD (create, read, update, delete) для работы с данными. Для извлечения данных из таблиц в SQL используется инструкция SELECT. Знать детали SQL-запросов вам не нужно, т.к. Entity Framework заботится о преобразовании LINQ-запросов в SQL.

Для получения всех данных из таблицы вам даже не нужно использовать LINQ-запрос, вы можете просто использовать свойство класса контекста, ссылающееся на класс модели и имеющее тип DbSet<T>. Entity Framework создаст запрос в базу данных для загрузки всех данных из таблицы, связанной с этим классом модели. Давайте добавим метод GetAllCustomers() в наш консольный проект, который мы создали ранее, чтобы извлечь все данные покупателей (т.к. мы еще не рассмотрели вставку данных с помощью Entity Framework, чтобы протестировать примеры выборки данных, вы можете заполнить таблицы Customers и Orders вручную, используя средства Visual Studio или SQL Server Management Studio):

Запрос context.Customers в этом примере извлечет все данные из таблицы Customers. Для запуска примера, вы можете вызвать метод GetAllCustomers() в методе Main() консольного приложения. Для этого примера Entity Framework сгенерирует следующий SQL-код (здесь я привожу фрагменты кода SQL для тех читателей, которые хорошо знакомы с T-SQL и хотят знать как EF транслирует запросы LINQ в SQL):

Код в этом примере возможно покажется несколько перегруженным, за счет использования псевдонима Extent1 для таблицы Customers и других псевдонимов для столбцов, а также явного указания схемы по умолчанию dbo. Это связано с тем, что Entity Framework имеет общий алгоритм построения запросов, который не только обслуживает этот очень простой запрос в примере, но также используется и для гораздо более сложных сценариев, в которых могут понадобиться эти псевдонимы.

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

Загрузка всех данных из таблицы с помощью Entity Framework

Стоит также отметить, что в этом примере мы используем отложенный LINQ-запрос. Если в вашем приложении предполагается делать несколько выборок данных в одном месте, отложенные запросы могут сильно ухудшить производительность приложения. Давайте рассмотрим пример:

Указание столбцов, условий и сортировки в запросе

В запросе данных из таблицы вы можете указать порядок сортировки, который будет использован для выборки данных. Для этого используется вспомогательный метод OrderBy(). Ниже показан пример, в котором данные заказчика сортируются по фамилии:

Приведенный выше код использует LINQ для создания запроса выборки сортированных данных из таблицы, а затем перебирает результаты запроса и отображает имя и фамилию каждого покупателя. После получения коллекции данных через свойство Customers класса контекста, вы можете использовать вспомогательные LINQ-методы OrderBy(), GroupBy() и Join() для сортировки, группировки данных на основе ключа и соединения таблиц. Эти методы будут транслированы на одноименные инструкции языка SQL.

Другой часто определяемой задачей при выборке данных, является их фильтрация на основе определенного условия. В SQL для этих целей используется оператор WHERE, LINQ содержит одноименный метод Where(), с помощью которого можно добавить дополнительное условие для загрузки данных:

В этом запросе мы выбираем всех покупателей старше 25 лет.

До сих пор мы выбирали из базы данных только коллекцию объектов модели, т.е. коллекцию IQueryable<Customer>. Зачастую извлекать все данные не нужно, а нужно извлечь данные только из определенного столбца таблицы, создавая проекцию таблицы. Такой подход позволяет улучшать производительность, когда запрашиваются данные из таблицы, содержащей много столбцов, а в приложении нужно работать только с одним или несколькими столбцами.

Например, мы могли бы захотеть выбирать только фамилии покупателей из таблицы базы данных и отбрасывать всю другую информацию. Для этих целей в LINQ используется метод Select(), которому передается делегат, в котором выбираются нужные свойства модели. Этот метод возвращает уже не коллекцию объектов Customer, а коллекцию простых типов, например, для фамилий он вернет тип IQueryable<string>. Ниже показан соответствующий пример:

Этот запрос транслируется в следующий SQL-код:

Здесь видно, что из таблицы будут выбираться данные только фамилии покупателей (столбец LastName указывается после инструкции SELECT). На рисунке ниже наглядно показано, какие данные выбирает этот запрос:

Загрузка данных из одного столбца таблицы с помощью Entity Framework

Загрузка данных из нескольких столбцов таблицы с помощью Entity Framework

В нашем примере мы загружаем данные имен и фамилий в анонимный объект. Иногда бывает необходимо загрузить данные в объект модели, инициализировав только некоторые его свойства. В контексте нашего примера это означает, что мы могли бы создать коллекцию объектов Customers, в которую загрузили бы из базы данных всех пользователей, указав только два свойства FirstName и LastName. Для этих целей вы могли бы предположить, что нужно написать следующий пример:

Если вы запустите этот пример, то в приложении возникнет исключение NotSupportedException, в котором говорится, что Entity Framework не может использовать сложный тип Customer с запросом LINQ to Entities. Для этих целей вы должны сначала загрузить коллекцию анонимных объектов, которая инициализируется из базы данных, а затем создать коллекцию объектов Customer, которая инициализируется из коллекции анонимных объектов. Эту задачу можно выполнить в одном запросе, функционально разделив сложный запрос на две части – первая будет использоваться Entity Framework для извлечения данных из базы, вторая будет работать в памяти приложения и инициализировать коллекцию объектов Customer. В качестве разделителя нужно использовать метод AsEnumerable():

Метод AsEnumerable() в LINQ просто преобразует коллекцию IQueryable к IEnumerable. В простых приложениях, работающих с коллекциями данный метод практически не используется, т.к. в нем нет смысла – интерфейс IQueryable является производным от интерфейса IEnumerable. Но этот метод оказывает существенное влияние при использовании с Entity Framework, указывая, что цепочку методов в запросе до его вызова нужно выполнить, отправив запрос к базе данных, а последующие методы будут оперировать уже на коллекции в памяти приложения. Если вы запустите этот пример, то можете убедиться в его работоспособности.

Поиск в запросе

Пока вы видели запросы, которые возвращают коллекцию объектов из базы данных, но иногда нужно чтобы запрос возвращал один объект. Наиболее распространенным сценарием для запросов, возвращающих один объект, является поиск определенного объекта с заданным ключом. DbContext API позволяет делать это очень просто, используя метод Find() класса DbSet. Этот метод принимает значение, которое нужно найти в таблице и возвращает соответствующий объект, если он найден, или null если не найден.

Поиск в запросе в Entity Framework использует следующую последовательность:

Сначала выполняется поиск в коллекции объектов, уже загруженных из базы данных в память приложения.

Если к коллекции добавлялись новые объекты, то поиск выполняется и в них.

Выполняется поиск в базе данных в объектах, которые еще не были загружены в память приложения.

Чтобы увидеть реализацию поиска, давайте добавим новый метод FindCustomer() в котором мы будем принимать идентификатор покупателя от пользователя, путем ввода его в консоль и затем будем искать покупателя с соответствующим идентификатором в базе данных:

Метод Find() осуществляет поиск по первичному ключу таблицы. Как вы знаете, первичные ключи бывают составными, поэтому методу Find() можно передать несколько значений, для поиска в ключах, при этом эти значения должны следовать в том же порядке, в котором свойства первичных ключей определены в классе модели. Напомню, что в Code-First для этого используется атрибут аннотаций данных Column, с переданным ему параметром Order, либо метод HasColumnOrder(), если вы используете для настроек Fluent API.

Если вам нужно выполнить поиск в обычных столбцах, не являющихся ключами таблицы, то для этого можно использовать условие через метод Where(). Например, если мы хотим найти всех покупателей, чья фамилия начинается на русскую букву “В”, то можем использовать следующий запрос:

Локальные данные

Во всех предыдущих примерах мы использовали запрос к свойству класса контекста типа DbSet (context.Customers). Как говорилось ранее, использование этого свойства приводит к созданию запроса к базе для выборки всех данных из привязанной таблицы. Мы также использовали метод Find(), который ищет в памяти приложения данные до создания запроса к этой базе данных, в уже загруженных ранее данных.

Могут быть случаи, когда вы захотите использовать более сложный запрос для данных, которые уже были загружены из базы данных и находятся в памяти приложения, т.е использовать отложенный запрос, чтобы избежать повторной отправки запроса к базе данных. Например, мы могли бы загружать данные всех пользователей только при первом запуске приложения и сохранить их в каком-то локальном для приложения объекте, а затем в различных частях приложения создавать запросы к уже существующей коллекции, чтобы всякий раз не загружать ее снова.

Еще одной причиной использования такой локальной коллекции данных, является то, что в приложении в разных местах могут добавляться новые данные к этой коллекции, которые должны быть также использованы в запросах. При использовании не отложенного метода ToList(), запрос сразу же отправляется в базу данных и извлекаются данные, содержащиеся в базе данных, игнорируя новые данные в памяти приложения. Наглядно это показано на следующем примере:

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

Entity Framework позволяет хранить локальные данные для объектов DbSet, определяя свойство Local в этом классе. Это свойство вернет все данные, которые были загружены из базы данных плюс любые добавленные новые данные в приложении. Данные, которые были помечены в приложении как удаленные, но при этом еще не удаленные из базы данных, также будут фильтроваться в запросе.

Давайте начнем с очень простой задачи и определим, сколько на текущий момент находится объектов в памяти приложения:

Этот метод позволяет проверить, сколько объектов Customer на данный момент находятся в памяти приложения. Если вы запустите приложение с вызовом этого метода, вы увидите, что количество объектов равно нулю. Мы получаем нулевой результат, потому что мы не выполняем никаких запросов, чтобы загрузить покупателей из базы данных, и мы не добавляли новые объекты Customer в коде. Давайте немного изменим этот метод, и запросим некоторые данные из базы:

У меня в базе данных находится три заказчика, поэтому данный пример вернет следующий результат:

Загрузка объектов из памяти приложения Entity Framework

Перебор содержимого DbSet в цикле по каждому элементу является одним из способов, чтобы получить все данные из памяти приложения, но это немного неэффективно, чтобы каждый раз выполнять цикл просто ради загрузки данных. К счастью, DbContext API включает специальный метод Load() в классе DbSet, который можно вызвать для ручного запуска процесса загрузки данных из базы. Ниже показано использование этого метода (не забудьте указать пространство имен System.Data.Entity):

Этот код гораздо лаконичнее, чем тот, что мы использовали ранее. В сборке System.Data.Entity определен также расширяющий IQueryable<T> метод Load(), поэтому мы можем использовать его не только для загрузки всех данных из таблицы, но также использовать LINQ-методы для сужения выборки. Например, следующий запрос посчитает, сколько находится в памяти объектов Customer, чей возраст превышает 25 лет:

Использование особенностей коллекции ObservableCollection

Если вы смотрели примеры использования локальных данных довольно внимательно, то должны были увидеть, что свойство Local возвращает специальный тип обобщенной коллекции ObservableCollection. Этот тип коллекции позволяет получать уведомления, когда добавляются или удаляются элементы из коллекции. Коллекция ObservableCollection полезна в ряде сценариев, работающих с привязкой данных. Например, мы ее использовали при рассмотрении WPF в статье “Привязка к коллекции объектов”, чтобы изменять графический интерфейс приложения, когда добавлялись данные.

Эта коллекция имеет событие CollectionChanged, в обработчике которого мы можем вносить полезные действия. В контексте локальных данных Entity Framework это событие возникает когда мы загружаем или удаляем данные из базы, работаем с данными в памяти приложения или добавляем новые объекты в DbContext. Ниже показан пример:

Этот код добавляет новый обработчик событий изменения коллекции локальных данных. Этот обработчик указан через лямбда-выражения, хотя можно было и добавить отдельный метод. С помощью этого обработчика мы фиксируем в консоли, когда добавляется, а когда удаляется запись из коллекции. Если вы запустите приложение с вызовом метода LocalLinqQueryies(), то вы увидите, что EF загрузит из базы данных три записи в локальную коллекцию:

Обработка событий изменения локальных данных в Entity Framework

Использование такого типа коллекций может упростить работу с Entity Framework в приложениях, которые работают с привязкой данных, например, в приложениях WPF.

Читайте также: