c# web. Занятие 04
TRANSCRIPT
Темы лекции: Entity Framework.
Практическое задание: Entity Framework.
Тренер: Игорь Шкулипа, к.т.н.
Разработка Веб-приложений на платформе Microsoft .NET Framework.
Занятие 4
http://www.slideshare.net/IgorShkulipa 2
ORMORM (англ. Object-relational mapping, рус. Объектно-реляционное
отображение) — технология программирования, которая связываетбазы данных с концепциями объектно-ориентированных языковпрограммирования, создавая «виртуальную объектную базу данных».
Суть проблемы, которая решается с помощью ORM-слоя, заключается внеобходимости преобразования объектных структур в памятиприложения в форму, удобную для сохранения в реляционных базахданных, а также для решения обратной задачи — развертыванияреляционной модели в объектную, с сохранением свойств объектов иотношений между ними.
Entity Framework представляет специальную объектно-ориентированную технологию на базе .NET для работы с данными.Если традиционные средства ADO.NET позволяют создаватьподключения, команды и прочие объекты для взаимодействия сбазами данных, то EF представляет собой более высокий уровеньабстракции, который позволяет абстрагироваться от самой базыданных и работать с данными независимо от типа хранилища. если нафизическом уровне мы оперируем таблицами, индексами, первичнымии внешними ключами, но на концептуальном уровне, который нампредлагает EF, мы уже работаем с объектами.
http://www.slideshare.net/IgorShkulipa 3
Entity Framework
Центральной концепцией Entity Framework является понятие сущностиили entity. Сущность представляет набор данных, ассоциированных сопределенным объектом. Поэтому данная технология предполагаетработу не с таблицами, а с объектами и их наборами.
Любая сущность, как и любой объект из реального мира, обладает рядомсвойств. Свойства не обязательно представляют простые данные типаint, но и могут представлять более комплексные структуры данных. Иу каждой сущности может быть одно или несколько свойств, которыебудут отличать эту сущность от других и будут уникально определятьэту сущность. Подобные свойства называют ключами.
При этом сущности могут быть связаны ассоциативной связью один-ко-многим, один-ко-одному и многие-ко-многим, подобно тому, как вреальной базе данных происходит связь через внешние ключи.
Отличительной чертой Entity Framework является использованиезапросов LINQ для выборки данных из БД. С помощью LINQ мыможем не только извлекать определенные строки, хранящие объекты,из БД, но и получать объекты, связанные различными ассоциативнымисвязями.
http://www.slideshare.net/IgorShkulipa 4
Entity Data Model
Другим ключевым понятием является Entity Data Model. Эта модельсопоставляет классы сущностей с реальными таблицами в БД.
Entity Data Model состоит из трех уровней: концептуального, уровеньхранилища и уровень сопоставления (маппинга).
• На концептуальном уровне происходит определение классовсущностей, используемых в приложении.
• Уровень хранилища определяет таблицы, столбцы, отношениямежду таблицами и типы данных, с которыми сопоставляетсяиспользуемая база данных.
• Уровень сопоставления (маппинга) служит посредником междупредыдущими двумя, определяя сопоставление между свойствамикласса сущности и столбцами таблиц.
Таким образом, мы можем через классы, определенные в приложении,взаимодействовать с таблицами из базы данных.
http://www.slideshare.net/IgorShkulipa 5
Способы взаимодействия с БД
Entity Framework предполагает три возможных способа взаимодействия сбазой данных:
• Database first: Entity Framework создает набор классов,которые отражают модель конкретной базы данных
• Model first: сначала разработчик создает модель базы данных,по которой затем Entity Framework создает реальную базу данныхна сервере.
• Code first: разработчик создает класс модели данных, которыебудут храниться в БД, а затем Entity Framework по этой моделигенерирует базу данных и ее таблицы
http://www.slideshare.net/IgorShkulipa 6
Создание запросов
Чтобы эффективно работать с Entity Framework нужно в первую очередьзнать, как выполнять запросы к хранилищу данных с использованиемEF. Хотя к счастью в Entity Framework создавать запросы очень легко,так как в основном для этого применяются методы LINQ, которыенапоминают SQL-выражения.
Вначале производится общий запрос к хранилищу данных. Затемсвойство объекта представляет объект-коллекцию DbSet и возвращаетобъект IEnumerable<T>. То есть мы можем получить все объекты изтаблицы, например, следующим образом:
IEnumerable<SomeTable> someTable = tableContainer.SomeTable;
foreach(var st in someTable )
{
Console.WriteLine(st.Name);
}
http://www.slideshare.net/IgorShkulipa 7
Взаимодействие с данными. Подход Model First
http://www.slideshare.net/IgorShkulipa 17
Code-First к существующей базе данных
Данный подход также представляет способ взаимодействия Code First,однако база данных не генерируется автоматически, а создаетсясамим разработчиком. Иногда программисты называют данный подходCode Second. Данный подход удобен, когда у нас уже есть базаданных.
http://www.slideshare.net/IgorShkulipa 18
Code-First к существующей базе данных
http://www.slideshare.net/IgorShkulipa 19
Database First
Database First был первым подходом, который появился в EntityFramework. Данный подход во многом похож на Model First и подходитдля тех случаев, когда разработчик уже имеет готовую базу данных.
Чтобы Entity Framework мог получить доступ к базе данных, в системедолжен быть установлен соответствующий провайдер. Так, VisualStudio уже поддерживает соответствующую инфраструктуру для СУБДMS SQL Server. Для остальных СУБД, например, MySQL, Oracle идругих надо устанавливать соответствующие провайдеры.
http://www.slideshare.net/IgorShkulipa 25
Database First
Текст
http://www.slideshare.net/IgorShkulipa 26
Строка подключения
Иногда может потребоваться динамически изменять местоположение илиназвание базы данных, к которой идет подключения. В этом случаенам надо указать стрку подключения. По умолчанию Visual Studioдобавляет в проекты файл конфигурации. В проектах для десктопныхприложений этот файл называется App.config, в проектах веб-приложений это файл Web.config. Но вне зависимости от типа проектафайл конфигурации имеет определенную структуру и элементы, средикоторых также есть также элемент connectionStrings, определяющийстроки подключения.
http://www.slideshare.net/IgorShkulipa 27
Навигационные свойства
public partial class Person
{
public Person()
{
this.Team = new HashSet<Team>();
}
public int PID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Middle { get; set; }
public System.DateTime Birthday { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
//Навигационные свойства задают связи между таблицами
public virtual Position Position { get; set; }
public virtual ICollection<Team> Team { get; set; }
}
http://www.slideshare.net/IgorShkulipa 28
Связь один ко многим
public partial class Person
{
public Person()
{
this.Team = new HashSet<Team>();
}
public int PID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Middle { get; set; }
public System.DateTime Birthday { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public virtual Position Position { get; set; }
public virtual ICollection<Team> Team { get; set; }
}
public partial class Position
{
public Position()
{
this.Person = new HashSet<Person>();
}
public int POSID { get; set; }
public string PName { get; set; }
public virtual ICollection<Person> Person { get; set; }
}
http://www.slideshare.net/IgorShkulipa 29
Связь многие ко многим
public partial class Person
{
public Person()
{
this.Team = new HashSet<Team>();
}
public int PID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Middle { get; set; }
public System.DateTime Birthday { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public virtual Position Position { get; set; }
public virtual ICollection<Team> Team { get; set; }
}
public partial class Team
{
public Team()
{
this.Person = new HashSet<Person>();
}
public int TID { get; set; }
public string TName { get; set; }
public virtual ICollection<Person> Person { get; set; }
}
http://www.slideshare.net/IgorShkulipa 30
Основные операции с данными
Большинство операций с данными представляют собой CRUD-операции(Create, Read, Update, Delete), то есть получение данных, создание,обновление и удаление. Entity Framework позволяет легко производитьданные операции.
http://www.slideshare.net/IgorShkulipa 31
Паттерн «Репозиторий»
Одним из наиболее часто используемых паттернов при работе с даннымиявляется паттерн Репозиторий.
Репозиторий позволяет абстрагироваться от конкретных подключений кисточникам данных, с которыми работает программа, и являетсяпромежуточным звеном между классами, непосредственновзаимодействующими с данными, и остальной программой.
http://www.slideshare.net/IgorShkulipa 32
Пример см. Занятие №3. Интерфейс
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
void Update(T entity, T newValue);
IQueryable<T> Find(Expression<Func<T, bool>> predicate);
IQueryable<T> SelectAll();
void SubmitAll();
}
http://www.slideshare.net/IgorShkulipa 33
Реализация
public class Repository<T> : IRepository<T> where T : class {
protected DbContext DBContext;
public Repository(DbContext dataContext) {
DBContext = dataContext;
}
public void Insert(T entity) {
DBContext.Set<T>().Add(entity);
}
public void Delete(T entity) {
DBContext.Set<T>().Remove(entity);
}
public void Update(T entity, T newValue) {
var entry = DBContext.Entry<T>(entity);
entry.CurrentValues.SetValues(newValue);
entry.State = EntityState.Modified;
}
public IQueryable<T> Find(Expression<Func<T, bool>> predicate) {
return DBContext.Set<T>().Where(predicate);
}
public IQueryable<T> SelectAll() {
return DBContext.Set<T>();
}
public void SubmitAll() {
DBContext.SaveChanges();
}
}
http://www.slideshare.net/IgorShkulipa 34
Модифицированный контракт
[DataContract(Namespace = "WCFS1")]
public class Contact
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Middle { get; set; }
[DataMember]
public string Surname { get; set; }
[DataMember]
public DateTime Birthday { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Phone { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public string Position { get; set; }
[DataMember]
public List<string> Teams { get; set; }
}
http://www.slideshare.net/IgorShkulipa 35
Служба
public class Service1 : IService1
{
IRepository<Person> persons;
IRepository<Position> positions;
IRepository<Team> teams;
Model1Container model;
public Service1(){
model = new Model1Container();
persons = new Repository<Person>(model);
positions = new Repository<Position>(model);
teams = new Repository<Team>(model);
}
public List<string> GetNames(){
var p = persons.SelectAll();
var res = from pe in p.ToArray<Person>()
where true
select pe.Name;
return res.ToList<string>();
}
public Contact GetData(string name){
Contact res = new Contact();
var pers = from p in persons.SelectAll()
where p.Name == name
select p;
res.Name=pers.ToArray<Person>()[0].Name;
...
return res;
}
http://www.slideshare.net/IgorShkulipa 36
Модификация на клиенте.
public class ContactViewModel: INotifyPropertyChanged
{
...
public string DetailsText
{
get
{
string result= CurrentContact.Name + "\n" +
CurrentContact.Middle + "\n" +
CurrentContact.Surname + "\n" +
CurrentContact.Birthday.ToString() + "\n" +
CurrentContact.Address + "\n" +
CurrentContact.Phone + "\n" +
CurrentContact.Email + "\n"+
CurrentContact.Position+"\n";
if (CurrentContact.Teams!=null)
foreach (string t in CurrentContact.Teams)
{
result += t + "\n";
}
return result;
}
}
}
http://www.slideshare.net/IgorShkulipa 38
Лабораторная работа №4.
Спроектировать и реализовать базу данных для лабораторной работы №3с использованием Entity Framework и паттерна «Репозиторий».