Многие разработчики добавляют в приложения код доступа к данным, когда база данных уже существует. Entity Framework поддерживает подход для работы с существующими базами данных, который называется Database-First, с самого своего первого появления (остальные подходы Model-First и Code-First были добавлены позже в версиях EF 4 и EF 4.1 соответственно).
Подход Database-First подразумевает создание графической модели Edmx из существующей базы данных. В этой статье описаны шаги для работы с этим подходом. Мы будем использовать все тот же пример веб-приложения ASP.NET, который использовали при рассмотрении подходов Code-First и Model-First.
Создание модели данных
Первым шагом при работе с подходом Database-First является проектирование базы данных. Фактически подход Database-First является противоположным подходу Model-First: при подходе Model-First мы сначала создаем графическую модель, а затем на ее основе генерируем или изменяем базу данных и наоборот, при подходе Database-First мы сначала создаем и проектируем базу данных, а затем на ее основе создаем графическую модель. Мы не будем создавать новую базу данных, а воспользуемся базой данных MyShop1, которую мы сгенерировали в предыдущей статье. Если вы хотите ознакомиться с деталями создания баз данных в СУБД SQL Server, то можете посетить раздел нашего сайта “SQL Server 2012 и T-SQL”.
- Добавьте новый проект библиотеки классов в ваше решение. Для этого в окне Solution Explorer щелкните правой кнопкой мыши по имени решения и выберите в контекстном меню команду Add –> New Project. Выберите шаблон библиотеки классов (Class Library), назовите его DatabaseFirst и нажмите кнопку Add.
- Щелкните по имени созданного проекта правой кнопкой мыши в окне Solution Explorer и выберите в контекстном меню команду Add –> New Item. В открывшемся диалоговом окне найдите шаблон ADO NET Entity Data Model на вкладке Data, задайте ему произвольное имя и щелкните по кнопке Add.
- После этого в открывшемся окне Entity Data Model Wizard нужно выбрать подход для работы с Entity Framework. Выберите вариант EF Designer from database который предполагает создание модели EDMX из существующей базы данных, что подразумевает под собой использование подхода Database-First.
- В открывшемся диалоговом окне настройте подключение к базе данных MyShop1 и нажмите кнопку Next (Далее).
- В следующем окне выберите версию Entity Framework 6.x и нажмите кнопку Next.
- Visual Studio извлекает информацию из базы данных. Через некоторое время, мастер Entity Data Model Wizard попросит вас выбрать элементы базы данных, которые вы хотите использовать в вашем приложении, как показано на рисунке:
Отметьте галочку на элементе Tables, чтобы выбрать все таблицы, содержащиеся в базе данных. В данном окне можно выбрать различные объекты базы данных, которые нужно отразить на сущностную модель данных, в том числе представления, хранимые процедуры и функции.
Обратите внимание на наличие некоторых настроек в этом окне. Настройка “Pluralize or singularize generated object names” позволяет настроить имена сгенерированных сущностных классов. Например, если бы у нас были в базе данных таблицы с именами Customers и Orders, и мы бы выбрали эту настройку, Entity Framework сгенерировал бы сущностные классы с именами Customer и Order (т.е. в единственном числе, используя правила английского языка). При этом свойства класса контекста, через которые можно загрузить коллекцию этих объектов, имели бы имена Customers и Orders. Настройка “Include foreign key columns in the model” позволяет включить поддержку проецирования отношений между таблицами.
Нажмите кнопку Finish (Готово). Entity Framework сгенерирует графическую модель EDMX для нашего примера.
- Постройте решение, командой Build –> Solution, чтобы Visual Studio скомпилировало наше приложение и автоматически сгенерировало класс контекста для кода доступа к базе данных.
Работа с данными
Думаю как вы уже поняли, код работы с данными в Entity Framework не зависит от выбранного подхода к проектированию модели данных. Поэтому, чтобы просто не копировать разметку веб-формы Default.aspx и ее код обработчика, которые мы использовали в предыдущих статьях при рассмотрении Code-First и Model-First, давайте немного расширим функциональность этой формы и добавим возможность просматривать записи в таблице Customer.
Для этого, сначала добавьте ссылку на проект DatabaseFirst в проект веб-приложения и строку подключения из файла App.config проекта DatabaseFirst в файл Web.config проекта веб-приложения. Затем отредактируйте разметку веб-формы, как показано ниже:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="ProfessorWeb.EntityFramework.Default" %>
<!DOCTYPE html>
<html>
<head runat="server">
<title>Code-First в Entity Framework</title>
</head>
<body>
<div class="form">
<form id="form1" runat="server" enctype="multipart/form-data">
<h3>Данные заказчика</h3>
<div class="data">
<div>
<label>Имя</label>
<input name="firstname" />
</div>
<div>
<label>Фамилия</label>
<input name="lastname" />
</div>
<div>
<label>Email</label>
<input name="email" />
</div>
<div>
<label>Возраст</label>
<input name="age" />
</div>
<div>
<label>Фото</label>
<input type="file" name="photo" />
</div>
<input type="submit" value="Вставить в БД" />
</div>
</form>
</div>
<table>
<asp:Repeater ID="Repeater1" runat="server" ItemType="DatabaseFirst.CustomerSet"
SelectMethod="GetCustomers">
<HeaderTemplate>
<tr>
<th>Id</th>
<th>Имя</th>
<th>Фамилия</th>
<th>Возраст</th>
<th>Email</th>
<th>Фото</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# Item.CustomerId %></td>
<td><%# Item.FirstName %></td>
<td><%# Item.LastName %></td>
<td><%# Item.Age + " лет" %></td>
<td><%# Item.Email %></td>
<td><img id="img" runat="server" src="<%# LoadImage(Item.Photo) %>" /></td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<style>
.form { width: 470px; margin: 20px auto; background: #888; border-radius: 5px; padding: 5px; }
form { background: #fff; border-radius: 2px; }
.data { border-top: 1px solid #d5d5d5; padding: 10px 15px; }
.data div { margin: 8px 0; }
h3 { padding: 10px 15px; margin: 0; }
label { min-width: 100px; display: block; float: left; }
input[type="submit"] { margin-top: 10px; }
table { margin: 10px auto }
th, td { padding: 8px; }
th { background: #28a4fa; color: white; font-weight: bold; }
tr:nth-of-type(even) { background: #eee; }
tr:nth-of-type(odd) { background: #fffbd6; }
td img { max-width: 50px; max-height: 50px; }
</style>
</body>
</html>
Файл отделенного кода Default.aspx.cs с кодом обработчиков, выглядит следующим образом:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.ModelBinding;
using System.IO;
using DatabaseFirst;
namespace ProfessorWeb.EntityFramework
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
CustomerSet customer = new CustomerSet();
// Получить данные из формы с помощью средств
// привязки моделей ASP.NET
IValueProvider provider =
new FormValueProvider(ModelBindingExecutionContext);
if (TryUpdateModel<CustomerSet>(customer, provider))
{
// Загрузить фото профиля с помощью средств .NET
HttpPostedFile photo = Request.Files["photo"];
if (photo != null)
{
BinaryReader b = new BinaryReader(photo.InputStream);
customer.Photo = b.ReadBytes((int)photo.InputStream.Length);
}
// В этой точке непосредственно начинается работа с Entity Framework
// Создать объект контекста
MyShop1Entities context = new MyShop1Entities();
// Вставить данные в таблицу Customers с помощью LINQ
context.CustomerSet.Add(customer);
// Сохранить изменения в БД
context.SaveChanges();
Repeater1.DataBind();
}
}
}
// Загрузить данные всех пользователей
public IEnumerable<CustomerSet> GetCustomers()
{
// Создать объект контекста
MyShop1Entities context = new MyShop1Entities();
return context.CustomerSet.AsQueryable();
}
// Загрузить изображение из базы данных
public string LoadImage(byte[] photo)
{
return "data:image/jpg;base64," + Convert.ToBase64String(photo);
}
}
}
Запустив это приложение вы сможете добавлять данные в таблицу Customer и автоматически наблюдать результат этих изменений:
Итак, на этом мы заканчиваем рассмотрение базовых подходов для работы с Entity Framework. В примерах последующих статей мы будем использовать в основном подход Code-First, хотя вас никто не ограничивает в использовании наиболее удобного подхода.


