Опубликован: 08.07.2011 | Доступ: свободный | Студентов: 1772 / 93 | Оценка: 4.15 / 4.08 | Длительность: 15:28:00
Лекция 8:

Разработка многофункциональных бизнес-приложений

Создание модели и сервисов данных

Создание EDM-модели данных рассматривалось в лекциях "Разработка приложения на базе WPF" и "Разработка Silverlight-приложений" . Исходной базой данных для EDM-модели модели является существующая база данных сотрудников организации – PersonalEnterprice. В Web-проект добавим папку DataAccess и в ней создадим EDM-модель EmployeeModel ( рис. 10.17).

Модель данных

Рис. 10.17. Модель данных

Таблица Employee имеет свойства, приведенные в табл. 8.1., а для таблицы Title свойства приведены в таблица 10.2.

Таблица 10.1. Свойства таблицы Employee
Свойство Назначение
ID Суррогатный ключ
FirstName Имя
SecondName Отчество
LastName Фамилия
TitleID Внешний ключ для таблицы Title
Role Роль/группа
Email Адрес электронной почты
Phone Телефон
Inn ИНН
FirstData Дата приема на работу
LastDate Дата увольнения
Picture Фотография
Title Связь с таблицей Title
Таблица 10.2. Свойства таблицы Title
Свойство Назначение
ID Суррогатный ключ
Title1 Должность
Employees Связь с таблицей Employee

При генерации EDM-модели создается класс PersonalEnterpriceEntities, который наследуется от класса ObjectContext. Класс PersonalEnterpriceEntities содержит описание сущностей базы данных PersonalEnterprice как свойств, метод добавления сущностей и навигации. После создания EDM-модели необходимо перекомпилировать проект.

Следующим шагом проектирования приложения является создание службы WCF RIA Services. В Web проекте создадим папку DomainModel в неё добавим экземпляр класса Domain Service Class с именем EmployeeDomainService.cs ( рис. 10.18).

Добавление Domain Service Class

увеличить изображение
Рис. 10.18. Добавление Domain Service Class

При добавлении сервиса WCF RIA Services необходимо в окне Add New Domain Service Class установить галочки для поля доступности сервиса для клиента ( Enable client access ), полей сущностей Employee и Title, а также разрешить редактирование сущностей – столбец Enable editing ( рис. 10.19).

Настройка добавления Domain Service Class

Рис. 10.19. Настройка добавления Domain Service Class

В результате добавления EDM-модели и сервиса WCF RIA Services в проекте будут сформированы в папке DataAccess файлы EmployeeModel.edmx, EmployeeModel.Designer.cs, а в папке DomainModel – EmployeeDomainService.cs и EmployeeDomainService.metadata.cs ( рис. 10.20).

Обозреватель решений проекта. Серверная часть

Рис. 10.20. Обозреватель решений проекта. Серверная часть

Созданный серверный класс EmployeeDomainService является, в общем случае, потомком класса DomainService, в нашем случае – это потомок класса LinqToEntitiesDomainService<PersonalEnterpriceEntities>, который обеспечивает доступ к данным на стороне сервера. Код класса EmployeeDomainService приведен в приложении.

Класс EmployeeDomainService помечен атрибутом [ EnableClientAccess() ], который обеспечивает доступ к сервису со стороны клиента. Методы GetEmployees() и GetTitles() класса предназначены для загрузки в приложение данных из базы, а методы Insert(), Update() и Delete() – для манипулирования данными.

Класс EmployeeDomainService.metadata.cs содержим метаданные о сущностях модели данных. Код класса EmployeeMetadata приведен в приложении.

Для разрабатываемого приложения необходима связь от таблицы Employee к таблице Title, поэтому в класс EmployeeMetadata необходимо добавить коллекцию Titles.

EntityCollection<Title> Titles { get; set; }

Метаданные используются, в частности, для генерации элементов контроля в клиентской части приложения и валидации данных. Свойства данных задаются с помощью атрибутов пространства имен System.ComponentModel.DataAnnotations. Если свойства не помечать специальными атрибутами, то в элементах контроля им будут присваиваться метки в соответствии с именами свойств, например FirstName, а порядок формирования элементов, например в элементе контроля DataGrid, будет соответствовать порядку данных в таблице и соответственно для сущности данных. Так, если для свойства Picture необходимо задать метку Фото и в списке свойств в таблице поместить её на первое место, то необходимо для атрибута Display определить свойства Name и Order.

[Display(Name = "Фото", Order = 0)]
public byte[ ] Picture { get; set; }

Перечень свойств атрибута Display приведен в табл.8.3

Таблица 10.3. Свойства атрибута Display
Имя Описание
AutoGenerateField Получает или задает значение, указывающее, нужно ли для отображения этого поля автоматически создавать пользовательский интерфейс.
AutoGenerateFilter Получает или задает значение, которое используется для фильтрации.
Description Получает или задает значение, которое используется для отображения описания пользовательского интерфейса.
GroupName Получает или задает значение, используемое для группировки полей в пользовательском интерфейсе.
Name Получает или задает значение, которое используется для отображения в элементе пользовательского интерфейса.
Order Получает или задает порядковый вес столбца.
Prompt Получает или задает значение, которое будет использоваться для задания подсказки в элементе пользовательского интерфейса.
ResourceType Получает или задает тип, содержащий ресурсы для свойств ShortName, Name, Prompt и Description.
ShortName Получает или задает значение, используемое в качестве метки столбца сетки.
TypeId При реализации в производном классе возвращает уникальный идентификатор для этого Attribute.

Для свойств класса EmployeeMetadata необходимо указать атрибут [ Display ], который будет использованы в интерфейсных элементах. Для атрибута Titles дополнительно укажем атрибут [ Include ], который предписывает сформировать коллекцию объектов Title в соответствии со свойствами навигации. Код модифицированного класса EmployeeMetadata приведен в приложении.

При построении сервиса WCF RIA Services на клиенте автоматически генерируется файл EnterpriceBusinessApplication.Web.g.cs, который можно найти в клиентском проекте EnterpriceBusinessApplication, если выделить данный проект и нажать кнопку Показать все файлы ( рис. 10.21).

Обозреватель решений проекта. Клиентская часть

Рис. 10.21. Обозреватель решений проекта. Клиентская часть

В файле EnterpriceBusinessApplication.Web.g.cs, в частности, имеются классы сущностей, аналогичные классам серверной части приложения и класс EmployeeDomainContext, который является наследником класса DomainContext и обеспечивает доступ к данным и методам сервиса со стороны клиента.

Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. 
Вопрос, как отследить и отключить добавление элемента в Items?

Максим Спиридонов
Максим Спиридонов

В пятой лекции на второй странице в компиляторе выскакивает ошибка в строчке :

ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;

Ошибка CS0029

Не удается неявно преобразовать тип "System.Data.Entity.DbSet<WpfApplProject.Employee>" в "System.Data.Entity.Core.Objects.ObjectQuery<WpfApplProject.Employee>".

в using прописал все как положено, здесь похоже именно с преобразованием типов проблемы