Часть 1 Услуги WCF RIA. Получение данных.
Часть 2 Услуги WCF RIA. Обновление данных.
Часть 3 Услуги WCF RIA. Мы реализуем шаблон Модель-Представление-ViewModel (MVVM).
Часть 4
Общая информация
В первой части мы познакомились с тем, что это за зверь WCF RIA Services, и создали приложение, которое кратко можно назвать «Hello world».Все было очень просто, красиво, а также «перетаскиванием».
Однако для создания реальных, больших и функциональных приложений еще предстоит многому научиться, например, какие функции доступны на стороне клиента и как их использовать.
В этом уроке мы углубимся в область получения данных на стороне клиента.
Вы также узнаете о соглашениях, используемых для методов, получающих данные, определенные в серверной части, и о том, как их настроить с помощью атрибутов.
Я расскажу о некоторых программных реализациях, которые можно использовать для получения данных на стороне клиента, и о том, как использовать данные, использующие источники, отличные от Entity Framework. Отправной точкой для изучения всего вышеперечисленного является проект, который был создан в предыдущей, первой части.
Шаг 1. Добавьте параметризованный запрос в доменную службу
После того, как мы создали сервис домена на предыдущем уроке, он выглядел так:Этот метод возвращает все записи из таблицы Tasks как тип перечисления IQueryable и не принимает аргументов.public IQueryable<Task> GetTasks() { return this.ObjectContext.Tasks; }
Если есть необходимость получить более конкретный запрос на стороне клиента, то нужно добавить в доменную службу метод, который в свою очередь будет автоматически доступен клиенту.
Также возможно возвращать данные типа IEnumerable, но если основной поставщик данных (Entity Framework или LINQ to SQL) возвращает IQueryable, то это нужно будет реализовать отдельно.
Сейчас мы модернизируем наше приложение таким образом, чтобы добавить возможность получения событий в заданном диапазоне дат. Для этого добавьте в службу домена следующий код: public IQueryable<Task> GetTasksByStartDate(
DateTime lowerDateTimeInclusive,
DateTime upperDateTimeInclusive)
{
return this.ObjectContext.Tasks.Where(
t => t.StartDate >= lowerDateTimeInclusive && t.StartDate <= upperDateTimeInclusive);
}
Шаг 2. Изменение пользовательского интерфейса для получения конкретных данных.
Для этого нам нужно добавить на нашу страницу несколько элементов.
Откройте MainPage.xaml. Переместите сетку так, чтобы над ней было свободное пространство для добавления элементов.
Используя перетаскивание, добавьте два текстовых поля и одну кнопку с панели инструментов.
Дайте созданным элементам имена соответственно: LowerDate, UpperDate, searchButton.
Измените содержимое кнопки на «Поиск по дате».
Шаг 3. Получение результата запроса на клиенте с использованием DomainContext
Как вы помните, DomainContext — это автоматически сгенерированный код, отражающий возможности серверной части приложения.То есть если доменная служба называется TasksDomainService, то клиентская часть приложения называется TasksDomainContext. Он обеспечивает возможность асинхронного доступа к серверной части, а также сохранения изменений, внесенных на стороне клиента.
Итак, каждый раз, когда сущности получаются от сервера путем выполнения запросов через контекст домена, он также сохраняет ссылки на эти объекты и некоторую другую дополнительную информацию, которая помогает отслеживать изменения.
И если эти объекты изменятся, контекст домена отправит на сервер только те сущности, которые нуждаются в обновлении.
Подробнее об этом в следующем уроке.
А пока давайте сосредоточимся на получении данных.
Добавьте событие Click к вновь созданной кнопке.
И добавьте следующий код в обработчик событий: private void searchButton_Click(object sender, RoutedEventArgs e)
{
DateTime lowerDateVal;
DateTime upperDateVal;
GetDates(out lowerDateVal, out upperDateVal);
TasksDomainContext context = new TasksDomainContext();
taskDataGrid.ItemsSource = context.Tasks;
EntityQuery<Task> query = context.GetTasksByStartDateQuery(lowerDateVal, upperDateVal);
LoadOperation<Task> loadOp = context.Load(query);
}
Стоит обратить внимание на последние 4 строки кода, так как первые 3 просто получают введенную дату из соответствующих полей и выглядят следующим образом: private void GetDates(out DateTime lowerDateVal, out DateTime upperDateVal)
{
lowerDateVal = DateTime.MinValue;
upperDateVal = DateTime.MaxValue;
if (!string.IsNullOrWhiteSpace(lowerDate.Text))
{
lowerDateVal = DateTime.Parse(lowerDate.Text);
}
if (!string.IsNullOrWhiteSpace(upperDate.Text))
{
upperDateVal = DateTime.Parse(upperDate.Text);
}
}
Чтобы иметь возможность вызывать серверную часть, необходимо создать экземпляр контекста домена.
Скорее всего, вам захочется создать этот экземпляр таким образом, чтобы он жил столько, сколько необходимо, ведь именно благодаря ему сохраняется вся необходимая информация для отслеживания изменений.
Например, при использовании шаблона MVVM рекомендуется создать и переместить экземпляр контекста предметной области в свойство модели представления.
Подробнее об этой теме мы поговорим на четвертом уроке.
Контекст домена предоставляет коллекции сущностей, которые, в свою очередь, включают наборы коллекций, возвращаемых доменом службы после обработки запросов.
На этом этапе домен службы предоставляет только сбор данных из таблицы Tasks. Обратите внимание, что этот код заменяет ItemsSource в DataGrid коллекцией Tasks перед выполнением любого запроса данных.
Это необходимо из-за того, что запросы, отправляемые контекстом домена, являются асинхронными и заменят содержимое коллекции только после прихода ответа от сервера.
Эта коллекция реализует интерфейс INotifyCollectionChanged и способна вызывать события, направленные на DataGrid (или любой связанный элемент), для обновления его содержимого.
Затем идет EntityQuery из контекста с аргументами, которые передаются соответствующему методу на сервере.
То есть здесь мы указываем то, что хотели бы получить, но звонок еще не произошел.
И, наконец, LoadOperation получается из контекста путем вызова метода Load. Здесь в теневом потоке осуществляется прямой контакт с сервером, и когда на сервере выполняется запрос и поступает ответ с необходимыми данными, вся информация автоматически обновляется в UI-потоке, чтобы быть актуальной.
В принципе, это то же самое, что происходит под прикрытием DomainDataSource из первого урока.
Шаг 4. Добавьте метод, возвращающий один объект
Чтобы метод не возвращал коллекцию, его необходимо объявить как таковой.
Далее, после компиляции, он будет доступен и на стороне клиента: public Task GetTask(int taskId)
{
return this.ObjectContext.Tasks.FirstOrDefault(t => t.TaskId == taskId);
}
Конвенция о настройках
Есть такая тенденция.NET-программирование, когда объем кода, который необходимо написать явно для обеспечения необходимых настроек, сокращается, но приходится соблюдать некоторые правила именования.
Возможно, вы еще не заметили этого, бегло взглянув на код службы домена, но он там уже используется.
Это не очень очевидно для методов, извлекающих данные, поскольку метод с любым именем будет работать одинаково хорошо.
Однако для операций обновления, удаления и создания необходимо придерживаться определенных правил, на основании которых службы WCF RIA ищут и выполняют необходимые методы, например UpdateTask, InsertTask, DeleteTask. Для каждой операции можно указать несколько опций.
И не забывайте о возможностях настройки с помощью атрибутов.
Например, для сторон, отправляющих запросы, вы можете украсить методы атрибутом [Query], что сделает ваш код более читабельным и простым для понимания.
Необходимо помнить, что тип возвращаемого значения также многое говорит о назначении метода.
Например, метод IEnumberable, возвращающий IQueryable, несет исключительную ответственность за получение данных.
Однако преимущество использования атрибута Query заключается в том, что он поддерживает некоторые дополнительные параметры, такие как максимальное количество возвращаемых результатов, что ограничивает их количество, даже если после запроса из базы данных возвращается больше, чем необходимо.
Пользовательские доменные службы
Что делать, если вы не хотите использовать Entity Framework? Как вариант, вы можете использовать LINQ to SQL. Я бы рекомендовал использовать Entity Framework с новыми проектами.И если можно со старыми.
LINQ to SQL поддерживается в службах WCF RIA через набор инструментов.
Однако многие используют другие стратегии доступа к данным, такие как nHibernate и другие источники данных, такие как Oracle, MySQL и многие другие.
Все это также можно использовать в WCF RIA Services, но вам необходимо определять объекты данных как простые сущности и использовать их дальше в коде по своему усмотрению.
Этот подход называется доменными службами POCO (Plain Old CLR Objects).
Чтобы создать такую службу домена, класс службы домена должен наследовать непосредственно от DomainService, а не от LinqToEntitiesDomainService. В помощнике создания при создании домена службы выберите «Класс обслуживания пустого домена» в раскрывающемся меню «Доступные классы контекста».
Затем определите сущности, верните коллекции этих сущностей IEnumerable, если ваш источник данных не поддерживает IQueryable, и делайте все, что вам нужно, в методах, основанных на источнике данных.
Далее вы должны спроектировать свой сервис в соответствии с исходными данными и объектами, с которыми вы работаете.
Эти объекты должны иметь свойства других объектов или наборов встроенных типов, поддерживаемых .
NET. Ключ, с помощью которого вы создаете свои сущности, определяет, что они должны иметь ключевые свойства, которые однозначно идентифицируют их.
Обычно «int» или «Guid».
Укажите это свойство как атрибут [Ключ].
Ниже приведен код, показывающий, как объявить домен службы POCO и его объекты: public class Foo
{
[Key]
public int FooId { get; set; }
public string Name { get; set; }
}
[EnableClientAccess()]
public class MyPOCODomainService : DomainService
{
public IEnumerable<Foo> GetFoos()
{
return new List<Foo> { new Foo { FooId = 42, Name = "Fred" } };
}
}
В дополнение к атрибуту [Key] если у вас есть свойства, которые сами являются типами сущностей (связанные сущности или объединения), вам необходимо добавить к этой сущности свойства, например ID, который сопоставляет ключевые поля.
Кроме того, непосредственно у свойства сущности необходимо указать атрибут [Ассоциация], который показывает идентификатор свойства, устанавливающего связи (отношения) и сообщающего, что это внешний ключ.
Вам также необходимо указать атрибут [Include] для свойства сущности, чтобы дочерняя сущность также всегда извлекалась при получении родительской сущности с помощью служб RIA.
После запуска проекта вы получите следующее окно, где можно выбрать по дате:
Видео к этому уроку
Источники
На Гитхаб Теги: #C++ #.NET #silverlight #wcf ria Services #silverlight #.
NET #C++
-
Фишер, Герман Эмиль
19 Oct, 24 -
Все, Что Вам Нужно Знать О Hostmonster
19 Oct, 24 -
10 Самых Популярных Видео С Рио-2016
19 Oct, 24