Использование Database-First

182

Многие разработчики добавляют в приложения код доступа к данным, когда база данных уже существует. 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”.

  1. Добавьте новый проект библиотеки классов в ваше решение. Для этого в окне Solution Explorer щелкните правой кнопкой мыши по имени решения и выберите в контекстном меню команду Add --> New Project. Выберите шаблон библиотеки классов (Class Library), назовите его DatabaseFirst и нажмите кнопку Add.

  2. Щелкните по имени созданного проекта правой кнопкой мыши в окне Solution Explorer и выберите в контекстном меню команду Add --> New Item. В открывшемся диалоговом окне найдите шаблон ADO NET Entity Data Model на вкладке Data, задайте ему произвольное имя и щелкните по кнопке Add.

    Добавление модели edmx
  3. После этого в открывшемся окне Entity Data Model Wizard нужно выбрать подход для работы с Entity Framework. Выберите вариант EF Designer from database который предполагает создание модели EDMX из существующей базы данных, что подразумевает под собой использование подхода Database-First.

  4. В открывшемся диалоговом окне настройте подключение к базе данных MyShop1 и нажмите кнопку Next (Далее).

  5. В следующем окне выберите версию Entity Framework 6.x и нажмите кнопку Next.

  6. Visual Studio извлекает информацию из базы данных. Через некоторое время, мастер Entity Data Model Wizard попросит вас выбрать элементы базы данных, которые вы хотите использовать в вашем приложении, как показано на рисунке:

    Выбор элементов базы данных, которые будут созданы в модели edmx
  7. Отметьте галочку на элементе 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 для нашего примера.

  8. Постройте решение, командой 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

Итак, на этом мы заканчиваем рассмотрение базовых подходов для работы с Entity Framework. В примерах последующих статей мы будем использовать в основном подход Code-First, хотя вас никто не ограничивает в использовании наиболее удобного подхода.

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

Пройди тесты
Лучший чат для C# программистов