Работа с Entity Framework

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

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

Вначале создадим новый проект. Пусть он называется EfDbApp. Первым делом нам надо добавить все необходимые пакеты Entity Framework в наш проект. Для этого в структуре проекта нажмем правой кнопкой мыши на узел References (Библиотеки) и в контекстном меню выберем пункт Manage NuGet Packages...:

Добавление Entity Framework в WPF

В открывшемся менеджере пакетов NuGet выберем пакет Entity Framework и установим его:

NuGet в WPF

Затем определим строку подключения в файле App.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
  
  <connectionStrings>
    <add name="DefaultConnection" 
         connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=mobiledb;Integrated Security=True" 
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
</configuration>

В данном случае мы будем использовать ту же базу данных mobiledb, которую создали в предыдущих темах. Однако даже если у нас нет базы данных mobiledb, то при первом обращении к базе данных Entity Framework создаст ее автоматически.

Теперь добавим в проект новую папку, которую назовем Models и в которой определим новый класс Phone:

public class Phone
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Company { get; set; }
    public int Price { get; set; }
}

Для взаимодействия с базой данных через Entity Framework нам нужен контекст данных, поэтому добавим в папку Models еще один класс, который назовем MobileContext:

using System.Data.Entity;

public class MobileContext : DbContext
{
    public MobileContext(): base("DefaultConnection")
    {

    }
    public DbSet<Phone> Phones { get; set; }
}

Класс контекста наследуется от класса DbContext. В своем конструкторе он передает в конструктор базового класса название строки подключения из файла App.config. Также в контексте данных определяется свойство по типу DbSet<Phone> - через него мы будем взаимодействовать с таблицей, которая хранит объекты Phone.

Теперь определим разметку интерфейса:

<Window x:Class="EfDbApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:EfDbApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="300">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="20 8 20 8" />
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="30" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <DataGrid AutoGenerateColumns="False" x:Name="phonesGrid">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Title}" Header="Модель" Width="100"/>
                <DataGridTextColumn Binding="{Binding Company}" Header="Производитель" Width="110"/>
                <DataGridTextColumn Binding="{Binding Price}" Header="Цена" Width="70"/>
            </DataGrid.Columns>
        </DataGrid>

        <StackPanel HorizontalAlignment="Center"  Grid.Row="1" Orientation="Horizontal">
            <Button x:Name="updateButton" Content="Обновить" Click="updateButton_Click" />
            <Button x:Name="deleteButton" Content="Удалить" Click="deleteButton_Click" />
        </StackPanel>
    </Grid>
</Window>

Как и в прошлой теме, на форме будет один элемент DataGrid и две кнопки для обновления и удаления.

Теперь определим в файле кода c# привязку данных и обработчики кнопок:

using System.Windows;
using EfDbApp.Models;
using System.Data.Entity;

namespace EfDbApp
{
    public partial class MainWindow : Window
    {
        MobileContext db;
        public MainWindow()
        {
            InitializeComponent();

            db = new MobileContext();
            db.Phones.Load(); // загружаем данные
            phonesGrid.ItemsSource = db.Phones.Local.ToBindingList(); // устанавливаем привязку к кэшу

            this.Closing += MainWindow_Closing;
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            db.Dispose();
        }

        private void updateButton_Click(object sender, RoutedEventArgs e)
        {
            db.SaveChanges();
        }

        private void deleteButton_Click(object sender, RoutedEventArgs e)
        {
            if (phonesGrid.SelectedItems.Count>0)
            {
                for (int i = 0; i < phonesGrid.SelectedItems.Count; i++)
                {
                    Phone phone = phonesGrid.SelectedItems[i] as Phone;
                    if (phone != null)
                    {
                        db.Phones.Remove(phone);
                    }
                }
            }
            db.SaveChanges();
        }
    }
}

С помощью следующих строк здесь мы загружаем данные из бд и выполняем привязку к ним элемента DataGrid:

db.Phones.Load();
phonesGrid.ItemsSource = db.Phones.Local.ToBindingList();

После окончания работы с контекстом данных нам нужно его утилизовать, а именно вызвать его метод Dispose(). Подходящим местом для этого является обработчик события Closing класса MainWindow.

И как и в прошлой теме, здесь нам достаточно ввести данные в строку грида, чтобы создать новый объект. Также мы можем изменять уже существующие значения в ячейках грида. И чтобы сохранить все изменения, в обработчике кнопки обновления вызывается метод db.SaveChanges().

Для удаления данных сначала вызывается метод db.Phones.Remove(phone) для всех удаляемых объектов, а затем также метод db.SaveChanges.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850