Указание строки соединения. Выбираем язык запросов

Самым известным, функциональным и широко используемым ORM в мире .NET является Entity Framework . Для работы с .NET Core была создана версия EF Core . Принцип работы EF Core остался тем же что у его предшественников, но это уже другая технология, так что сейчас ожидать полного набора функционала из Entity Framework 6 не приходится, но разработка проекта продолжается весьма активно. Из данной статьи вы узнаете как быстро приступить к использованию Entity Framework Core в ASP.NET Core проектах.

Для начала работы с EF Core необходимо установить необходимые библиотеки. Добавим пакеты Microsoft.EntityFrameworkCore.SqlServer и Microsoft.EntityFrameworkCore.Tools .

Для начала необходимо определиться с данными, которые будут храниться в базе данных. Я добавлю 2 класса User и Log , которые будут отвечать за данные пользователя и какие-то данные лога.

Public class User { public Guid Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } } public class Log { public long Id { get; set; } public DateTime UtcTime { get; set; } public string Data { get; set; } }

После этого можно создать контекст для работы с базой данных:

Class TestDbContext: DbContext { public TestDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity() .HasIndex(b => b.Email); } public DbSet Users { get; set; } public DbSet Logs { get; set; } }

DbContext — данный класс определяет контекст данных, используемый для работы с базой данных.

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

Сейчас необходимо настроить подключение к базе данных. Для этого откроем файл Startup.cs и в метод ConfigureServices добавим строку:

Services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Строку подключения зададим в файле конфигурации, по умолчанию это appsettings.json

"ConnectionStrings": { "DefaultConnection": "СТРОКА_ПОДКЛЮЧЕНИЯ_ЗДЕСЬ" }

Создание базы данных

Откроем Package Manager Console

И выполним команду Add-Migration InitialCreate

Это создаст файлы необходимые для создания структуры базы данных. Созданные файлы можно увидеть в созданной директории Migrations .

После этого выполним команду Update-Database и база будет создана.

Добавление логирования запросов

Сейчас давайте добавим логирование для всех API запросов. Для этого добавим класс LoggingMiddleware со следующим содержанием:

Public class LoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public LoggingMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task Invoke(HttpContext context, TestDbContext dbcontext) { if (context != null && context.Request.Path.ToString().ToLower().StartsWith("/api")) { using (var loggableResponseStream = new MemoryStream()) { var originalResponseStream = context.Response.Body; context.Response.Body = loggableResponseStream; try { var request = await FormatRequest(context.Request); await _next(context); var response = await FormatResponse(loggableResponseStream); loggableResponseStream.Seek(0, SeekOrigin.Begin); var newLog = new Log { Path = HttpUtility.UrlDecode(context.Request.Path + context.Request.QueryString), UtcTime = DateTime.UtcNow, Data = request, Response = response, StatusCode = context.Response.StatusCode, }; await loggableResponseStream.CopyToAsync(originalResponseStream); await dbcontext.Logs.AddAsync(newLog); dbcontext.SaveChanges(); } catch (Exception ex) { //Здесь можно добавить логирование ошибок throw; } finally { context.Response.Body = originalResponseStream; } } } } private static async Task FormatRequest(HttpRequest request) { request.EnableRewind(); string responseBody = new StreamReader(request.Body).ReadToEnd(); request.Body.Position = 0; return responseBody; } private static async Task FormatResponse(Stream loggableResponseStream) { loggableResponseStream.Position = 0; var buffer = new byte; await loggableResponseStream.ReadAsync(buffer, 0, buffer.Length); return JsonConvert.SerializeObject(Encoding.UTF8.GetString(buffer)); } }

А в файле Startup.cs в методе Configure добавим:

App.UseMiddleware();

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

Еще добавим контроллер для работы с пользователями, добавим там метод для получения информации обо всех пользователях.

")] public class UsersController: Controller { private readonly TestDbContext _context; public UsersController(TestDbContext context) { _context = context; } public async Task GetAll() { var users = await _context.Users.ToListAsync(); return Ok(users); } }

Это базовая информация, которая позволит вам быстро начать работать с Entity Framework Core .

Приятного программирования.

Последнее обновление: 31.10.2015

Entity Framework представляет специальную объектно-ориентированную технологию на базе фреймворка.NET для работы с данными. Если традиционные средства ADO.NET позволяют создавать подключения, команды и прочие объекты для взаимодействия с базами данных, то Entity Framework представляет собой более высокий уровень абстракции, который позволяет абстрагироваться от самой базы данных и работать с данными независимо от типа хранилища. Если на физическом уровне мы оперируем таблицами, индексами, первичными и внешними ключами, но на концептуальном уровне, который нам предлагает Entity Framework, мы уже работает с объектами.

Первая версия Entity Framework - 1.0 вышла еще в 2008 году и представляла очень ограниченную функциональность, базовую поддержку ORM (object-relational mapping - отображения данных на реальные объекты) и один единственный подход к взаимодействию с бд - Database First. С выходом версии 4.0 в 2010 году многое изменилось - с этого времени Entity Framework стал рекомендуемой технологией для доступа к данным, а в сам фреймворк были введены новые возможности взаимодействия с бд - подходы Model First и Code First.

Дополнительные улучшения функционала последовали с выходом версии 5.0 в 2012 году. И наконец, в 2013 году был выпущен Entity Framework 6.0, обладающий возможностью асинхронного доступа к данным.

Центральной концепцией Entity Framework является понятие сущности или entity. Сущность представляет набор данных, ассоциированных с определенным объектом. Поэтому данная технология предполагает работу не с таблицами, а с объектами и их наборами.

Любая сущность, как и любой объект из реального мира, обладает рядом свойств. Например, если сущность описывает человека, то мы можем выделить такие свойства, как имя, фамилия, рост, возраст, вес. Свойства необязательно представляют простые данные типа int, но и могут представлять более комплексные структуры данных. И у каждой сущности может быть одно или несколько свойств, которые будут отличать эту сущность от других и будут уникально определять эту сущность. Подобные свойства называют ключами .

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

Отличительной чертой Entity Framework является использование запросов LINQ для выборки данных из БД. С помощью LINQ мы можем не только извлекать определенные строки, хранящие объекты, из бд, но и получать объекты, связанные различными ассоциативными связями.

Другим ключевым понятием является Entity Data Model . Эта модель сопоставляет классы сущностей с реальными таблицами в БД.

Entity Data Model состоит из трех уровней: концептуального, уровень хранилища и уровень сопоставления (маппинга).

На концептуальном уровне происходит определение классов сущностей, используемых в приложении.

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

Уровень сопоставления (маппинга) служит посредником между предыдущими двумя, определяя сопоставление между свойствами класса сущности и столбцами таблиц.

Таким образом, мы можем через классы, определенные в приложении, взаимодействовать с таблицами из базы данных.

Способы взаимодействия с БД

Entity Framework предполагает три возможных способа взаимодействия с базой данных:

    Database first : Entity Framework создает набор классов, которые отражают модель конкретной базы данных

    Model first : сначала разработчик создает модель базы данных, по которой затем Entity Framework создает реальную базу данных на сервере.

    Code first : разработчик создает класс модели данных, которые будут храниться в бд, а затем Entity Framework по этой модели генерирует базу данных и ее таблицы

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

  • Объектно-реляционный конструктор . Этот конструктор предоставляет многофункциональный пользовательский интерфейс для создания объектной модели из существующей базы данных. Данное средство, являющееся частью интегрированной среды разработки Visual Studio, лучше всего подходит для баз данных небольшого или среднего размера.
  • Средство создания кода SQLMetal . По своему набору параметров эта консольная программа несколько отличается от Объектно-реляционного конструктора. Данное средство лучше всего подходит для моделирования больших баз данных.
  • Редактор кода . Можно написать собственный код с помощью редактора кода Visual Studio или другого редактора кода. Этот подход может привести к большому числу ошибок, поэтому при наличии существующей базы данных, которую можно использовать для создания модели с помощью Объектно-реляционного конструктора или программы SQLMetal, использовать его не рекомендуется. Однако редактор кода становится ценным инструментом, когда требуется уточнить или изменить код, уже созданный с помощью других средств.

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

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq; using System.Data.Linq.Mapping; using System.Data.SqlClient; namespace LinqtoSQL { public class Customer { public string CustomerID { get; set; } public string City { get; set; } public override string ToString() { return CustomerID + "\t" + City; } } class Program { static void Main(string args) { DataContext db = new DataContext (@"Data Source=.\SQLEXPRESS; AttachDbFilename=|DataDirectory|\NORTHWND.MDF; Integrated Security=True; User Instance=True"); var results = from c in db.GetTable() where c.City == "Москва" select c; foreach (var c in results) Console.WriteLine("{0}\t{1}", c.CustomerID, c.City); Console.ReadKey(); } } }

В этом приложении есть класс Customer , который отображает таблицу Customers , и имеет поля CustomerID и City , отображающие поля этой таблицы. Объект класса DataContext задает входную точку в базу данных и имеет метод GetTable , который возвращает коллекцию определенного типа, в данном случае типа Customer .

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

Хранимая процедура извлекает из таблицы Products 10 самых дорогих продуктов и их цены:

USE GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER procedure . AS SET ROWCOUNT 10 SELECT Products.ProductName AS TenMostExpensiveProducts, Products.UnitPrice FROM Products ORDER BY Products.UnitPrice DESC

Для того чтобы вызвать эту процедуру из программы на языке C# и вывести результаты, достаточно написать всего 3 строки кода:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq; using System.Data.Linq.Mapping; namespace LinqtoSQL { class Program { static void Main(string args) { var db = new northwindDataContext(); foreach (var r in db.Ten_Most_Expensive_Products()) Console.WriteLine(r.TenMostExpensiveProducts + "\t" + r.UnitPrice); Console.ReadKey(); } } }

Обратите внимание, что входная точка в базу данных теперь создается конструктором класса northwindDataContext (в общем случае класс будет называться так: {имя файла отображения} DataContext ), которому больше не нужно передавать параметром строку соединения в явном виде.

10.1.3. ADO.NET Entity Framework

ADO.NET Entity Framework (EF) – объектно-ориентированная технология доступа к данным, является object-relational mapping (ORM) решением для.NET Framework от Microsoft . Предоставляет возможность взаимодействия с объектами как посредством LINQ в виде LINQ to Entities, так и с использованием Entity SQL. Для облегчения построения Веб-решений используется как ADO.NET Data Services, так и связка из Windows Communication Foundation и Windows Presentation Foundation, позволяющая строить многоуровневые приложения, реализуя один из шаблонов проектирования MVC, MVP или MVVM.

Платформа ADO.NET Entity Framework позволяет разработчикам создавать приложения для доступа к данным, работающие с концептуальной моделью приложения, а не напрямую с реляционной схемой хранения. Ее целью является уменьшение объема кода и усилий по обслуживанию приложений, ориентированных на обработку данных. Приложения Entity Framework дают следующие преимущества .

  • приложения могут работать концептуальной моделью в терминах предметной области – в том числе с наследуемыми типами, сложными элементами и связями;
  • приложения освобождаются от жестких зависимостей от конкретного ядра СУБД или схемы хранения;
  • сопоставления между концептуальной моделью и схемой, специфичной для конкретного хранилища, могут меняться без изменения кода приложения;
  • разработчики имеют возможность работать с согласованной моделью объектов приложения, которая может быть сопоставлена с различными схемами хранения, которые, возможно, реализованы в различных системах управления данными;
  • несколько концептуальных моделей могут быть сопоставлены с единой схемой хранения;
  • поддержка интегрированных в язык запросов (LINQ ) обеспечивает во время компиляции проверку синтаксиса запроса относительно концептуальной модели.
10.1.3.1. Компоненты Entity Framework

Платформа Entity Framework представляет собой набор технологий ADO.NET, обеспечивающих разработку приложений, связанных с обработкой данных . Архитекторам и разработчикам приложений, ориентированных на обработку данных, приходится учитывать необходимость достижения двух совершенно различных целей. Они должны моделировать сущности, связи и логику решаемых бизнес-задач, а также работать с ядрами СУБД, используемыми для сохранения и получения данных. Данные могут распределяться по нескольким системам хранения данных, в каждой из которых применяются свои протоколы, но даже в приложениях, работающих с одной системой хранения данных, необходимо поддерживать баланс между требованиями системы хранения данных и требованиями написания эффективного и удобного для обслуживания кода приложения.

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

Платформа Entity Framework является компонентом.NET Framework, поэтому приложения Entity Framework можно запускать на любом компьютере, на котором установлен.NET Framework 3.5 с пакетом обновления 1 (SP1).

10.1.3.1.1. Применение концептуальных моделей на практике

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

Физическая модель совершенствуется администраторами базы данных в целях повышения производительности, но программисты, которые разрабатывают код приложения, в основном вынуждены ограничиваться работой с логической моделью, подготавливая SQL-запросы и вызывая хранимые процедуры. Концептуальные модели в основном используются как инструмент для представления и обмена мнениями по поводу требований к приложению, поэтому чаще всего служат в качестве почти неизменных схем, которые рассматриваются и обсуждаются на ранних стадиях проекта, после чего перестают быть предметом внимания.

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

Entity Framework был представлен корпорацией Microsoft в 2008 году как основное средством взаимодействия между приложениями .NET и реляционными базами данных. Entity Framework — это инструмент, упрощающий сопоставление объектов в программном обеспечении с таблицами и столбцами реляционной базы данных.

  • Entity Framework (EF) — это ORM-фреймворк с открытым исходным кодом для ADO.NET , который является частью .NET Framework .
  • ORM обрабатывает создание соединений с базой данных и выполнение команд, а также результаты запросов и автоматическое предоставление этих результатов в качестве объектов приложения.
  • ORM также помогает отслеживать изменения объектов приложения и может сохранять эти изменения в базе данных.

Почему Entity Framework?

Entity Framework — это ORM , нацеленная на повышение производительности за счет сокращения задач по сохранению данных, используемых в приложениях.

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

На данный момент существуют и другие ORM , такие как NHibernate и LLBLGen Pro . Большинство ORM обычно помещают типы домена непосредственно в схему базы данных.

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


  • Entity Framework — это рекомендуемая Microsoft технология доступа к данным для новых приложений.
  • ADO.NET также будет непосредственно ссылаться на эту технологию для наборов данных и таблиц данных.
  • Entity Framework — это инструмент, в который активно вкладываются средства и усилия на протяжении уже нескольких лет.
  • Корпорация Microsoft рекомендует использовать Entity Framework с ADO.NET или LINQ для SQL для всех новых разработок.

Концептуальная модель

Для разработчиков, которые ведут проекты, ориентированные на базу данных, преимущество Entity Framework заключается в том, что он позволяет сосредоточиться на бизнес-домене. Хотите, чтобы ваше приложение не ограничивалось только тем, что может сделать база данных?

  • В Entity Framework основное внимание уделяется модели объектов в приложении, а не модели БД, которую вы используете для сохранения данных приложения.
  • Концептуальная модель может быть согласованной со схемой базы данных или кардинально отличаться.
  • Можно использовать Visual Designer для определения концептуальной модели, которая сможет генерировать классы — их вы будете использовать в своем приложении.
  • Можно просто определить классы и использовать функцию Entity Framework под названием Code First . Таким образом вы зададите концептуальную модель для Entity Framework .


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

Функции

Ниже перечислены основные функции Entity Framework . В этот список вошли наиболее важные функции фреймворка, а также те, о которых разработчики часто задают вопросы.

  • Entity Framework — это инструмент, созданный специалистами компании Microsoft .
  • Entity Framework разрабатывается как продукт с открытым исходным кодом.
  • Entity Framework больше не привязан и не зависит от цикла релизов .NET .
  • Работает с любой реляционной базой данных и с действующим провайдером Entity Framework .
  • Генерация команд SQL из LINQ в Entities .
  • Entity Framework создает параметризованные запросы.
  • Entity Framework позволяет вставлять, обновлять и удалять команды.
  • Работает с визуальной моделью или с вашими собственными классами.
  • Entity Framework поддерживает хранимые процедуры.

Перевод статьи «What is Entity Framework» был подготовлен дружной командой проекта

Хорошо Плохо

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

Создание Модели данных Entity (EDM)

Существует несколько подходов создания EDM. Рассмотрим их подробнее.

База данных вначале (Database first)

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

При таком варианте проектирования архитектуры приложения главная роль отводится структуре базы данных. Классы бизнес логики вынуждены адаптироваться под неё. Однако это позволяет максимально раскрыть потенциал используемой системы управления базами данных.

Чтобы использовать рассматриваемый подход в своем проекте, необходимо выбрать пункт "Add Item" в контекстном меню проекта и добавить описание Модели данных Entity (ADO.NET Entity Data Model).

В появившемся диалоге "Entity Data Model Wizard" нужно выбрать вариант "Generate from a database". После этого потребуется указать базу данных и параметры соединения с ней (выбрать или создать строку соединения). В результате в проект будет добавлен EDMX-файл, который содержит описание EDM в формате XML.

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

Каждый представленный здесь класс в терминологии Entity Framework называется сущностью. Все их свойства разделены на две группы:

  1. Связанные напрямую с полями базы данных: Id , Title , и т. д.
  2. Навигационные: Language , Publisher , Tags .

Последние не имеют прямых аналогов среди полей базы данных и созданы исходя из анализа связей таблиц. Они позволяют удобно и просто запрашивать связанную c данной сущностью информацию. Например, список книг на определенном языке можно получить используя коллекцию BookDetails у соответствующего экземпляра Language .

Кроме того, стоит обратить внимание, что между сущностями указаны не только связи, но и их тип. При этом символ "звездочка" обозначает неограниченное число элементов (many). Так в приведенном примере есть следующие варианты:

  • *–1 – тип One-to-many (��дна ко многим). Т.е. любой записи в таблице BookDetails соответствует одна запись в Language. И наоборот, одной записи в таблице Language может соответствовать любое число записей в BookDetails.
  • *–0..1 – также тип One-to-many (одна ко многим), но этом связь не обязательно должна существовать для каждой записи в таблице BookDetails.
  • *–* – этот вариант указывает на связь типа Many-to-many (многие ко многим). В частности любой книге (BookDetails) соответствует любое число ключевых слов (Tag), как и наоборот.

Модель вначале (Model first)

Следующий подход к разработке Модели данных Entity называется Модель вначале. Он является противоположностью предыдущего варианта. При этом изначально в дизайнере создается описание EDM, руководствуясь требованиями бизнес-логики. После чего на его основе генерируется база данных.

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

Добавление в проект описания EDM практически аналогично. Отличие только в диалоге "Entity Data Model Wizard", где необходимо выбрать пункт "Empty Model". После завершения работ по созданию Модели остается только сгенерировать базу данных. Для этого нужно выбрать пункт "Generate Database from Model" в контекстном меню дизайнера.

Код вначале (Code First)

В рассмотренных выше вариантах классы Модели получаются путем их автоматической генерации. А что если классы Модели уже есть? Или, например, удобнее написать их С# код, чем рисовать в дизайнере?

Начиная с версии 4.1 в Entity Framework еще один подход к разработке описания EDM – Код вначале. С его помощью можно создать базу данных на основе классов C# или Visual Basic. Причем для этого достаточно даже их самого простого варианта – POCO (Plain Old CLR Object).

Для использования этого подхода достаточно указать Entity Framework используемые типы. Большая часть работы делается на основе соглашений. Однако при необходимости можно использовать атрибуты для задания необходимых параметров.

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

Этот вариант будет рассмотрен чуть позже на конкретном примере. А сейчас давайте посмотрим, какие возможны варианты сопоставления классов и таблиц.

Соответствие наследования таблицам в базе данных

Независимо от используемого способа создания EDM, можно столкнуться с задачей, которая в языках высокого уровня решается с использованием наследования. Но каким образом можно отразить это в базе данных? Существует три подхода для решения этой проблемы.

Используем пример, чтобы сделать дальнейшее описание более понятным. Предположим, что в Модели автомобильного каталога существует базовый класс Car и два его наследника CivilCar и SportCar .

Таблица для каждого конкретного типа (Table per concrete type или TPC)

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

Для указанных выше классов их будет три: Cars, CivilCars и SportCars. Стоит учесть, что в случае необходимости получить полный список автомобилей, в запросе будут использоваться все эти таблицы.

Таблица для каждого типа (Table per type или TPT)

В данном случае будет создано несколько таблиц:

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

Таким образом, в предложенном примере будет основная таблица Cars и две вспомогательные – CivilCars и SportCars. Подобное решение может быть выгодно, если большая часть запросов требует только информацию, соответствующую свойствам класса Car . Например, наиболее часто выводится полный список автомобилей, а уже по выбранным моделям отображаются подробные данные.

Таблица для иерархий (Table per hierarchy или TPH)

Последний подход позволяет создать одну общую таблицу для всех классов. Тип, к которому относится конкретная запись, в этом случае указывается в специальным поле. Здесь есть принципиальный момент: необходимо чтобы все свойства, добавленные в классах-наследниках, могли принимать значение null . Дело в том, именно оно будет указываться в полях, у которых нет аналогов в сохраняемом экземпляре.

В рассматриваемом примере будет создана таблица Cars, содержащая перечень всех свойств всех наследников класса Car .

Указание строки соединения

После создания EDM может потребоваться указание строки соединения для Entity Framework. Обратите внимание, что при использовании дизайнера она будет автоматически внесена в конфигурацию приложения. А вот в случае применения подхода Код вначале, её необходимо добавить самостоятельно.

Использование файла конфигурации (app.config или web.config)

Строка соединения Entity Framework выглядит несколько отличающейся от привычного варианта, используемого в ADO.NET. Однако понятна с первого взгляда:

......... .........

В данном примере в файл web.config добавляется новая строка соединения с следующими параметрами:

  • name – имя строки соединения. В данном примере это BookCatalogEntities;
  • connectionString – параметры соединения для Entity Framework:
    • metadata – где расположены метаданные EDM. Три указанных файла отвечают за Контестную модель (csdl), Модель хранилища (ssdl) и Модель соотношения (msl).
    • provider – имя провайдера данных для Entity Framework. В данном случае это System.Data.SqlClient для работы с SQL Server или SQL Server Express.
    • provider connection string – параметры соединения. Содержимое этого параметра зависит от выбранного провайдера данных.
  • providerName – имя провайдера данных для приложения. Оно всегда равно System.Data.EntityClient .

При использовании подхода Код вначале отпадает необходимости в указании EDM. Поэтому строка приобретает более привычный вид:

Указание строки соединения в коде приложения

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

Есть два способа программного указания строки соединения:

  • создать её как обычную строку, используя string и StringBuilder .
  • воспользоваться специальным классом EntityConnectionStringBuilder , который предоставляет следующие свойства:
    • Metadata – соответствует секции metadata в варианте рассмотренном выше;
    • Provider – указывает используемого провайдера данных;
    • ProviderConnectionString – настраивает параметры соединения провайдера.
    • ConnectionString – строка соединения. Свойство доступно только для чтения.

Все что остается – создать новый контекст данных ObjectContext с новой строкой соединения. В этом с случае также придется создать самостоятельно все необходимые объекты типа ObjectSet . Цель указанных типов будет пояснена чуть ниже, а пока посмотрим на пример такого кода:

Var newConnection = new EntityConnectionStringBuilder() { Metadata = @"res://*/DBFirstCatalogModel.csdl|res://*/DBFirstCatalogModel.ssdl|res://*/DBFirstCatalogModel.msl", Provider = @"System.Data.SqlClient", ProviderConnectionString = @"data source=(local);initial catalog=BookCatalog;integrated security=True;multipleactiveresultsets=True;App=EntityFramework" }; using (var context = new ObjectContext(newConnection.ConnectionString)) { var catalog = context.CreateObjectSet(); var languages = context.CreateObjectSet(); var publishers = context.CreateObjectSet(); var tags = context.CreateObjectSet(); // Запросить данные... }

Выбираем язык запросов

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

  • Entity SQL – использует текстовый для представления запросов. Внешне схож с стандартным SQL, но отличается от него функциями. Необходимо отметить, что только с использованием Entity SQL можно напрямую обращаться к Клиентскому провайдеру данных Entity, минуя слой Службы объектов. В некоторых сценариях это может дать большой прирост в производительности.
  • LINQ to Entities – является диалектом языка запросов LINQ для Entity Framework и использует его синтаксис. Стоит отметить, что поддерживаются не все доступные методы. При этом их использование не является ошибкой на этапе компиляции. Однако в процессе выполнения приложения будет выброшено исключение NotSupportedException .

Какой язык предпоч��ительнее? Однозначного ответа быть не может. У каждого из них есть свои плюсы. Поэтому данные вопрос, с учетом текущей задачи, каждый должен решить для себя сам.

Принципы получения и модификации данных

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

  1. Обратиться с помощью Entity SQL или LINQ to Entities к слою Служб объектов.
  2. Использовать Entity SQL для запроса напрямую к слою Клиентского провайдера данных Entity.

Рассмотрим принцип использования только первого варианта.

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

Стоит отметить, что ObjectContext и DbContext не являются абстрактными. Механизм наследования используется только для того, чтобы добавить в новый класс свойства, отвечающие за доступ к данным. Их тип ObjectSet или DbSet соответственно, а имена совпадают с именами сущностей Модели. Эти свойства позволяют работать с объектами базы данных используя к LINQ to Entities.

Полученные объекты отслеживаются слоем Служб объектов. Поэтому при вызове метода сохранения изменений, база данных будут соответствующе модифицирована.

Давайте перейдем от теории к практике и посмотрим как реализована работа с Entity Framework в разрабатываемом демонстрационном веб-приложении.