При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Разработка многофункциональных бизнес-приложений
Создание модели и сервисов данных
Создание EDM-модели данных рассматривалось в лекциях "Разработка приложения на базе WPF" и "Разработка Silverlight-приложений" . Исходной базой данных для EDM-модели модели является существующая база данных сотрудников организации – PersonalEnterprice. В Web-проект добавим папку DataAccess и в ней создадим EDM-модель EmployeeModel ( рис. 10.17).
Таблица Employee имеет свойства, приведенные в табл. 8.1., а для таблицы Title свойства приведены в таблица 10.2.
Свойство | Назначение |
---|---|
ID | Суррогатный ключ |
Title1 | Должность |
Employees | Связь с таблицей Employee |
При генерации EDM-модели создается класс PersonalEnterpriceEntities, который наследуется от класса ObjectContext. Класс PersonalEnterpriceEntities содержит описание сущностей базы данных PersonalEnterprice как свойств, метод добавления сущностей и навигации. После создания EDM-модели необходимо перекомпилировать проект.
Следующим шагом проектирования приложения является создание службы WCF RIA Services. В Web проекте создадим папку DomainModel в неё добавим экземпляр класса Domain Service Class с именем EmployeeDomainService.cs ( рис. 10.18).
При добавлении сервиса WCF RIA Services необходимо в окне Add New Domain Service Class установить галочки для поля доступности сервиса для клиента ( Enable client access ), полей сущностей Employee и Title, а также разрешить редактирование сущностей – столбец Enable editing ( рис. 10.19).
В результате добавления EDM-модели и сервиса WCF RIA Services в проекте будут сформированы в папке DataAccess файлы EmployeeModel.edmx, EmployeeModel.Designer.cs, а в папке DomainModel – EmployeeDomainService.cs и EmployeeDomainService.metadata.cs ( рис. 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
Для свойств класса EmployeeMetadata необходимо указать атрибут [ Display ], который будет использованы в интерфейсных элементах. Для атрибута Titles дополнительно укажем атрибут [ Include ], который предписывает сформировать коллекцию объектов Title в соответствии со свойствами навигации. Код модифицированного класса EmployeeMetadata приведен в приложении.
При построении сервиса WCF RIA Services на клиенте автоматически генерируется файл EnterpriceBusinessApplication.Web.g.cs, который можно найти в клиентском проекте EnterpriceBusinessApplication, если выделить данный проект и нажать кнопку Показать все файлы ( рис. 10.21).
В файле EnterpriceBusinessApplication.Web.g.cs, в частности, имеются классы сущностей, аналогичные классам серверной части приложения и класс EmployeeDomainContext, который является наследником класса DomainContext и обеспечивает доступ к данным и методам сервиса со стороны клиента.