Pull to refresh
0

Почему я так сильно люблю EF, или Фичи, от которых сложно отказаться

Reading time 4 min
Views 10K
Недавно мы опубликовали статью, написанную по результатам посещения конференции DEVIntersection. Предлагаем вашему вниманию ещё одну полезную «выжимку», посвящённую Entity Framework (EF).

ORM-фреймворки уже давно стали для нас привычными инструментами для взаимодействия с базой данных. В частности, если вы занимаетесь разработкой приложений на платформе .NET, то, скорее всего, используете Entity Framework, и никого уже этим не удивить. Но, несмотря на популярность EF и обилие информации о нём, довольно часто складывается некорректное понимание, что это такое, зачем нужно и как его использовать. В этой статье мы рассмотрим самые важные, субъективно, фичи в Entity Framework 6.1.x. Необходимо сразу подчеркнуть, что EF не решит все проблемы взаимодействия с базой данных, но всё же поможет от многих избавиться.

Миграции и инициализация базы данных


EF позволяет генерировать классы миграций, основываясь на сущностях в контексте, которые, в свою очередь, реализуют методы Up() и Down(). Это позволяет двигаться вверх и вниз по цепочке миграций, тем самым управляя версией базы данных. Метод Seed(DbContext) позволяет добавить необходимые данные для инициализации базы. Это отличный способ быстро вносить изменения в базу данных, реагировать на новые требования или решать проблемы.

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

Lazy loading автоматически подгружает автоматические сущности или коллекции, связанные непосредственно с сущностью, по которой делается запрос в базу данных. У данного подхода есть недостатки, связанные с тем, что мы буквально вытаскиваем всё, что связано с нужными нам записями, при этом EF поместит их в контекст и будет трекать изменения этих записей. Мягко говоря, это может вызвать ряд проблем и неудобств.

public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Product> Products { get; set; }
}

Eager loading — позволяет подгрузить нужные сущности как часть запроса, используя метод Include.

var categories = context.Categories
.Include(p => p.Products).ToList();

Explicit Loading — это способ явно подтягивать нужные сущности, если Lazy Loading был отключен.

var category = context.categories.Find(1);
context.Entry(category).Collection(p => p.Products).Load();

System.ComponentModel.DataAnnotations (DataAnnotation)
— способ настройки модели таким образом, чтобы как EF, так и ASP.NET MVC понимали правила настройки. DataAnnotation позволяет указывать правила валидации или просто описывать первичные и внешние ключи, используя атрибуты ([Key], [RoreignKey], [Index], [StringLength], [Required], [NotMapped] и другие).

System.Data.Entity.ModelConfiguration.Conventions (Code firs conventions)
— ряд правил, которые применяются к модели и описывают её с помощью классов C#. Можно указывать навигационные свойства, первичные и внешние ключи, сложные типы.

Совместное редактирование


Бывают случаи, когда одну и ту же запись редактируют несколько пользователей. Допустим, один только достал запись для редактирования, а другой сохранил изменения. После того, как первый решил сохранить свои изменения, мы будем перезаписывать уже изменённые записи, что может привести к потере важных данных. Зачастую ничего страшного не происходит, если просто применять последние изменения.

Само собой, есть несколько способов решать проблему одновременного редактирования данных. Давайте рассмотрим Pessimistic и Optimistic concurrency.

Pessimistic Concurrency — один из способов предотвращения потери данных, подразумевающий блокировку сущностей. Если кто-то уже редактирует сущность, то мы не дадим другим пользователям редактировать её же, поэтому нам не нужно думать, какие записи сохранять. Данный подход может вызвать ряд проблем и замедлить работу приложения, поэтому он поддерживается немногими СУБД. В EF также не реализована поддержка pessimistic concurrency.

Альтернативой этому способу можно считать Optimistic Concurrency. При этом подходе конфликтные ситуации допускаются и обрабатываются, и здесь EF уже может помочь. Конфликт можно обработать путём реагирования на OptimisticConcurrencyException, кидаемый Entity Framework, но сначала нужно научить EF понимать, когда возник конфликт. Для этого необходимо добавить свойство, с помощью которого можно было бы следить за версиями (как правило, rowversion), а затем указать, что это ConcurencyToken. Это можно сделать через метод IsConcurrencyToken, указав, за каким свойством следует следить.

Логирование


Начиная с EF 6 появилась возможность перехватывать команды, отправляемые в базу данных. Таким образом, можно реализовать логирование, менять или отменять выполнение команд. Свойству DbContext.Database.Log можно присвоить делегат, который принимает строку как параметр. Он выполнит обработку этой строки, например, просто сохранит логи в файл или выведет в консоль. По сути, логирование — это просто перехват команд, и если нужно реализовать собственную логику, то для этого нужна реализация IDbCommandInterceptor, с помощью которого можно подписываться на события и делать необходимые операции с контекстом базы данных.

Connection Resilency


Если по каким-то причинам отвалился интернет, но EF при этом выполняет запрос или сохраняет изменения, то теперь есть возможность повторить ещё раз. Это очень полезная фича, если, например, база хостится на Azure и с интернетом могут возникнуть проблемы. Настраивать можно с помощью IDbConnectionStrategy.

* * *

Конечно, это далеко не все фичи, которые нам предоставляет EF. На первый взгляд может сложиться впечатление, что они не такие уж и важные. Однако, как нам кажется, эти фичи пригодятся в любом проекте и дадут необходимую гибкость и функциональность в процессе разработки приложений.
Tags:
Hubs:
+12
Comments 0
Comments Leave a comment

Articles

Information

Website
www.nixsolutions.com
Registered
Founded
1994
Employees
1,001–5,000 employees