Wcf ria services что это
Пример создания WCF-сервиса, работающего внутри службы Windows
Windows Communication Foundation – программная платформа от Microsoft для создания, настройки и развертывания распределенных сетевых сервисов. WCF-runtime и его пространство имен System.ServiceModel, представляющее его главный программный интерфейс, это преемник технологий создания распределенных систем, успешно применяемых разработчиками для создания распределенных приложений на платформе Windows в последнее десятилетие. Разберём тестовый пример создания WCF-сервиса.
Открываем Visual Studio 2015 и создаём новый проект типа Class Library. Проект назовём WCFMyServiceLibrary.
Файл Class1.cs переименуем в MyService.cs и добавим ещё один класс, файл для которого назовём IMyService.cs.
Добавим ссылку на сборку System.ServiceModel.
На этом разработка сервиса завершена. Переходим к созданию службы Windows, которая будет контейнером для данного сервиса.
В том же решении (Solution) создадим новый проект типа «Служба Windows». Называем проект WindowsServiceHostForMyService.
Затем файл Service1.cs (только что созданного проекта) переименуем в MyService.cs. В этот проект добавим ссылку на сборку System.ServiceModel, а также не забываем указывать в файле MyService.cs директивы:
В классе MyService добавляем новый член:
Также необходимо добавить ссылку на проект WCFMyServiceLibrary, который находится в этом же решении:
Затем в классе MyService изменим метод OnStart таким образом, чтобы в этом методе добавлялись конечные точки нашего сервиса (endpoint):
Затем реализуем остановку сервиса в методе OnStop:
Затем в Обозревателе решения — двойной клик на файле MyService.cs (проекта WindowsServiceHostForMyService) откроет этот файл в режиме конструктора (Design Mode).
На пустом пространстве вызываем контекстное меню (щелчок правой кнопкой мыши) и выбираем «Добавить установщик».
При этом будет создан новый класс ProjectInstaller.cs
Переименуем файл ProjectInstaller.cs в MyServiceInstaller.cs.
При этом выйдет окно с вопросом, следует ли переименовать зависимые объекты – отвечаем «Да».
Добавим в файл ссылку
Затем изменим код конструктора класса MyServiceInstaller:
Заметим, что вызов метода InitializeComponent() мы заблокировали с помощью комментария.
На этом разработка службы Windows завершена. Собираем всё решение (Build Solution) и переходим к следующему этапу – установка службы Windows.
Для установки нашей службы создадим bat-файл (с произвольным названием, например Install_Windows_Service.bat) следующего содержания:
Нужно скопировать этот bat-файл в ту же папку, где находится скомпилированный файл WindowsServiceHostForMyService.exe (вам нужно заранее продумать, в какой папке будет лежать этот файл, который будет всегда запущен в качестве службы Windows).
Запускаем bat-файл, после чего наша программа WindowsServiceHostForMyService.exe будет установлена в качестве службы Windows.
Запустим эту службу с помощью стандартной программы управления службами.
Следующий этап – разработка клиентского приложения для использования предоставляемых сервисом услуг.
Для этого прежде всего нужно организовать так называемый «переходник» — Service Proxy – набор настроек, описывающих сервис для клиентского приложения.
Воспользуемся для этого стандартной утилитой SvcUtil.exe. Создадим файл Generate_Proxy.bat следующего содержания
Запустим этот файл (стандартная утилита SvcUtil.exe находится в папке C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin).
Этот файл нужно запустить во время работы нашего сервиса, т.е. в данном случае, после успешного запуска службы Windows WindowsServiceHostForMyService.
В случае успешного запуска, программа SvcUtil.exe сгенерирует 2 файла — MyServiceProxy.cs и App.config.
Эти файлы необходимо добавить для клиентского приложения, чтобы это приложение могло вызывать методы нашей службы (чуть ниже вы узнаете, что файл App.config я решил не добавлять — обойдёмся и без него).
Примечание. Аналогичного результата можно было добиться, запустив
Т.е. можно запускать эту утилиту, указав только одну конечную точку, либо http либо net.tcp.
В том же решении (Solution) создадим обычное приложение Windows Forms. Назовем его WindowsFormsApplication1
Добавим в этот проект ссылку на System.ServiceModel и, конечно же,
Добавим в этот проект файл MyServiceProxy.cs (именно его мы сгенерировали утилитой SvcUtil.exe). При этом следует добавить в файл MyServiceProxy.cs следующие строки:
После этого, мы сможем ссылаться на класс MyServiceClient (этот класс создан программой SvcUtil.exe), указав в файле формы директиву.
Поступим неординарно – и не будем добавлять файл App.Config в проект клиента!
Затем набросаем на форму 3 кнопки, текстовое поле textBox1 (пользователь вводит сюда строку для отправки на сервер) и поле richTextbox1 (имитация подсистемы сообщений нашего приложения – именно в это поле будут поступать сообщения от программы, в том числе и те, что вернул нам сервис)
Кнопка btn_Start – создаёт клиента
Кнопка btn_Send – отправляет сервису текстовую строку из текстового поля
Кнопка btn_Close – удаляет клиента из памяти и закрывает приложение
Компилируем и запускаем с другой машины из той же сети – и тестируем сервис, нажав сначала btn_Start, а затем отправляя сервису сообщения нажатием btn_Send.
Заметим, что в данном примере на клиенте мы совсем не использовали конечную точку
http://localhost:9001/MyService
а работали только с
net.tcp://localhost:9002/MyService
(вы легко сможете это сделать самостоятельно – раз уж вам net.tcp по плечу, то уж http-то с закрытыми глазами сделаете).
Кроме того, мы не использовали файл App.config, создав на клиенте конечную точку не с помощью настроек, а с помощью кода C#. Причины тому – субъективные – автор не любит возиться с XML-настройками, а по возможности всё делает явно в коде. Спасибо за внимание!
Лирическое отступление. Автор статейки познакомился с языком C# в марте сего года, первое приложение на C# написал в мае (до этого много лет формошлёпил на Delphi и даже на MS Access).
WCF RIA Services. Обновление данных. Часть 3
В предыдущем уроке мы более подробно ознакомились с возможностями получения данных в WCF RIA Services. Сегодня поговорим о процессе обновления данных, который является более сложным.
Вступительной частью является проект, созданный во втором уроке.
IQueryable и магия деревьев выражений
В первом уроке мы создали службу домена, которая выглядела приблизительно так:
Если немного подумать о том, как он работает, то станет ясно, что происходит извлечение всей таблицы из БД при каждом вызове метода.
Однако это только на первый взгляд. Давайте разберемся, что же такое деревья выражений и отложенное выполнение?
Итак. Когда происходит вызов метода «GetTasks» — это не означает, что происходит запрос к БД и извлекаются данные. На самом деле происходит всего-навсего построение дерева выражений и возврат его как IQueryable, которое просто описывает, что может быть возвращено этим методом. В данном случае, теоретически есть возможность получить всю таблицу Tasks. Так же дерево выражений описывает то, что может быть возвращено клиентской стороне. Непосредственно выполнение запроса и процесс извлечения данных из БД происходит лишь в тот момент, когда что-то пытается изменять коллекцию, которую предоставляет/описывает дерево выражений. Однако остается возможность изменения дерева выражений получателем после того, как запрос отправлен, а это в свою очередь может изменить и результаты, которыми в итоге заполнится коллекция.
Возможность изменения дерева выражений присутствует и непосредственно перед процессом извлечений данных. Например:
Во второй строчке происходит привязка коллекции Tasks через контекст домена, который на самом деле еще пустой, так как происходит формирование контекста домена. Затем происходит получение EntityQuery из контекста. Тут еще нет непосредственного выполнения запроса и извлечения данных из БД. Однако EntityQuery позволяет сформировать дерево выражений, на основе которого на сервере, после вызова метода будет сформирован запрос к БД и произойдет извлечение данных. В данном случае возможно извлечение всей таблицы. И только при вызове метода «Load» происходит передача измененного дерева выражений, который включает фильтр «Where», а после отработки запроса будет возвращена только одна строка, у которой в столбце «ID» будет значение «1». Ппроизойдет асинхронный вызов к серверной части, передастся дерево выражений и произойдет извлечение. Однако даже на серверной части запрос уже будет модифицирован и из БД будет возвращена всего одна строка. Вы можете убедиться в этом сами, просто просмотрев, какие SQL запросы будут выполнены при вызове этого метода. То есть создание отдельного метода для извлечения нескольких строк и одной строки из БД отпадает, что облегчает жизнь программисту.
Кэширование в DomainContext и отслеживание изменений
Логику работы разобрали. Но перед тем, как перейдем к разбору кода необходимо разложить по полочкам еще и некоторые концепции работы WCF RIA Services. Вышесказанное далеко не все, что происходит за кулисами контекста домена. Например, имеют место быть вызов прокси. Любые сущности или их коллекции, которые Вы получаете кэшируются контекстом домена на стороне клиента. Именно по этой причине появляется возможность, как в примере выше, привязать ItemsSource к коллекции Tasks до непосредственного выполнения запроса. Данная коллекция будет изменена на актуальную, а данные в UI автоматически обновятся в тот момент, когда придет ответ после асинхронного вызова к серверу. В дополнение к кэшированию, контекст домена хранит информацию о любых изменениях кэшированной сущности, и поэтому всегда знает, если происходит изменение, удаление или добавление.
На основе всего, что мы уже узнали, можно сделать вывод, что не нужно каждый раз делать вызовы серверной части при любом изменении объекта. Можно, например, накопить изменения объектов а потом один раз осуществить вызов серверной части и все изменения будут правильно внесены и обработаны.
Шаг 1: Добавление метода обновления данных в службу домена.
В первом уроке, при создании службы домена мы воспользовались мастером создания. И если поставить галочку напротив каждой сущности в столбце «Добавить редактирование», то получим автоматически сгенерированные методы для каждой сущности, реализующие функционал CRUD.
Выглядеть код будет следующим образом:
Эти методы являются простыми обертками над соответствующими операциями entity framework.
Шаг 2: Добавление элементов в UI для новых действий
Добавим две кнопки, которые будут добавлять новое задание и сохранять измененную коллекцию в БД.
Шаг 3: Создаем новое задание, добавление его в контекст домена и сохранение изменений.
Добавим следующий код в обработчики событий «Click» новых кнопок соответственно:
Сначала добавляется переменная, с которой связывается контекст домена. Как уже упоминалось раньше, контекст домена должен жить столько, что б он мог отследить изменения и применить их, вызвав соответствующий метод на серверной части приложения. Поэтому мы отделили вызовы методов для добавления изменений в наш объект и сохранение этих изменений.
После нажатия на кнопку «Add Task», его обработчик замещает ItemsSource нашего DataGrid, что б заместить DomainDataSource, который мы подключили в первом уроке. Затем вызывается метод «Load», что б заполнить контекст домена нужной сущностью.
Далее создаем и заполняем новый объект Tasks и добавляем его к коллекции контекста домена Tasks. Эти изменения сразу же отобразятся в UI, так как упомянутая коллекция реализует интерфейс INotifyCollectionChanged. Но, учтите, что все эти изменения применились, отобразились и сохранились в кэше контекста домена. Но не были изменены на серверной части и в БД. Для применения изменений необходимо вызвать метод SubmitChanges, который и вызывается при нажатии на соответствующую кнопку нашего приложения.
Когда Вы нажмете на кнопку «Add Task» — увидите, что добавилось новое задание, однако в поле «TaskId» значения всегда будут «0». Однако если нажать на кнопку «SubmitChanges», то через некоторое время, а именно после того как произойдет асинхронный вызов, выполнится запрос и вернутся данные обновятся и станут актуальными.
Асинхронное API контекста домена
Я уже это упоминал, но повторюсь еще разок. Такие методы как «Load» и «SubmitChanges» API контекста домена вызываются асинхронно. Это означает, что они не тормозят работу вызывающего их потока, в котором обычно находится UI. Они берут поток из пула потоков «за кулисами», делают вызов серверной части в фоновом режиме, и когда вызов отрабатывает, возвращаются в вызывающий поток UI и обновляют коллекцию сущностей и непосредственно сам UI.
Все это легко и красиво. Когда работает. Но в реальности всегда присутствует своя ложка дегтя. Бывает возникают проблемы со связью, или кто-то случайно подпортил строку соединения, или возникают конфликты распараллеливания в фоне. Но не смотря на все возможные сценарии необходимость знать когда выполнились вызовы и когда нужно предоставлять возможность двигаться дальше никуда не пропадает. Для этого можно воспользоваться парой способов: использовать тип возвращаемого значения или обратный вызов, который и будет вызываться, когда операция будет завершена.
Первый вариант заключается в работе с возвращаемым значением от асинхронно вызываемого метода. Метод Load возвращает LoadOperation, а метод SubmitChanges возвращает SubmitOperation. Они оба наследуют OperationBase и в силу этого предоставляют достаточное количество информации об операции, которую Вы можете использовать в процессе работы или после завершения операции. Так же они вызывают событие «Completed» по окончанию операции, и естественно у Вас есть возможность подписаться на это событие. Само собой доступны различные ошибки, срабатывания различных флагов и многое другое, что можно использовать при создании приложения.
Как альтернативу на подписку события «Completed» можно использовать вызов перегруженного метода «Load» или «SubmitChanges», которые возвращают соответственно Action и Action. Передаете ссылку на функцию обратного вызове и при завершении операции он автоматически вызывается.
WCF RIA Services. Получение данных. Часть 2
Общие сведения
В первой части мы ознакомились, что за зверь такой WCF RIA Services, и создали приложение, которое можно коротко назвать, как «Hello world». Все было очень просто, красиво, а так же «drag and drop». Однако для создания настоящих, больших и функциональных приложений нужно еще много чего выучить, например какие возможности доступны в клиентской части, и как их использовать. В этом уроке мы копнем немножко глубже в области получения данных на клиентской стороне. Так же Вы узнаете о конвенциях, которые используются для методов, получающих данные, определенные в серверной части, как их настраивать, используя атрибуты. Расскажу о некоторых программных реализациях, которые можно использовать для получения данных на стороне клиента и как использовать данные, которые используют отличные от Entity Framework источники.
Начальной точкой для изучения всего вышесказанного является проект, который был создан в предыдущей, первой части.
Шаг 1: Добавление в доменную службу параметризованного запроса
После того, как мы создали службу домена в предыдущем уроке, она имела такой вид:
Этот метод возвращает все записи из таблицы Tasks как перечислимый тип IQueryable и не принимает аргументов. Если же возникает необходимость получить на стороне клиента более специфический запрос, то необходимо добавить метод в службу домена, который в свою очередь будет автоматически доступен клиенту. Так же есть возможность возвращать данные типа IEnumerable, но если основной поставщик данных (Entity Framework или LINQ to SQL) возвращает IQueryable, то это нужно будет реализовать отдельно.
Сейчас модернизируем наше приложение таким образом, что б добавить возможность получать события в заданном диапазоне дат. Для этого в службу домена добавьте следующий код:
Шаг 2: Изменения UI для получения конкретизированных данных.
Для этого необходимо добавить несколько элементов на нашу страницу. Откройте MainPage.xaml. Сместите Grid таким образом, что б над ним было свободное место для добавления элементов. С помощью «Drag and drop» добавьте из Панели инструментов два TextBox и один Button. Дайте имена созданным элементам, соответственно: lowerDate, upperDate, searchButton.
Измените Content кнопки на «Search By Date».
Шаг 3: Получение результата запроса на клиенте, используя DomainContext
Как Вы помните, DomainContext – это автогенерируемый код, который представляет отражение возможностей серверной части приложения. То есть, если сервис домена называется TasksDomainService, то клиентская часть приложения называется TasksDomainContext. Он предоставляет возможность обращаться к серверной части в асинхронном режиме, а так же сохранять изменения, которые были внесены на клиентской стороне.
Так, каждый раз, когда происходит получение сущностей от сервера путем выполнения запросов через контекст домена, в нем так же сохраняются ссылки на эти объекты и некоторая другая дополнительная информация, помогающая отслеживать изменения. И в случае изменения этих объектов, контекст домена будет отправлять на сервер только те сущности, которые нуждаются в обновлении. Про это в следующем уроке. А сейчас давайте сфокусируемся на получении данных.
Добавьте на только что созданную кнопку событие «Click». А в обработчик этого события добавьте следующий код:
Обратить внимание следует на последние 4 строчки кода, так как первые 3 – просто получение введенной даты из соответствующих полей, и выглядит следующим образом:
Для того, что б можно было вызвать серверную часть необходимо создать экземпляр контекста домена. Скорее всего Вы захотите создать этот экземпляр таким образом, что б он прожил столько, сколько нужно, потому, что именно благодаря ему сохраняется вся необходимая информация для отслеживания изменений. Например, при использовании паттерна MVVM хорошей идеей будет создать и переместить экземпляр контекста домена в свойство модели вида. Более подробно поговорим на эту тему в четвертом уроке.
Контекст домена предоставляет коллекции сущностей, которые в свою очередь включают в себя наборы коллекций, возвращаемых доменом сервиса после отработки запросов. На данном этапе домен сервиса предоставляет только коллекцию данных из таблицы Tasks.
Обратите внимание, что данный код заменяет ItemsSource в DataGrid коллекцией Tasks до того, как производится какой либо запрос на получение данных. Так нужно в силу того, что запросы, отправляемые контекстом домена являются асинхронными, и заменят содержимое коллекции лишь после прихода ответа от сервера. Данная коллекция реализует интерфейс INotifyCollectionChanged и способна вызывать события, направленные на DataGrid (или любой связанный элемент) для обновления его содержимого.
Затем идет получение EntityQuery от контекста с аргументами, которые передаются в соответствующий метод на сервере. То есть тут мы указываем, что бы мы хотели получить, но вызов еще не происходит. И наконец-то происходит получение LoadOperation от контекста, путем вызова метода Load. Вот тут уже происходит непосредственно обращение к серверу в теневом потоке, а когда запрос выполниться на сервере и придет ответ с необходимыми данными — в потоке UI автоматически обновится вся информация на актуальную.
В принципе, это тоже самое, что происходит под покровом DomainDataSource из первого урока.
Шаг 4: Добавление метода, возвращающего единственный объект
Чтоб метод не возвращал коллекцию, его нужного так и объявить. Далее, после компиляции он будет так же доступен и на стороне клиента:
Конвенция о настройках
Есть такая тенденция в. NET программировании, когда уменьшается количество кода, необходимого явно прописывать для обеспечения нужных настроек, однако приходиться следовать некоторым правилам именования. Возможно Вы этого еще не заметили, бегло просматривая код службы домена, однако там уже это применяется. Это не очень очевидно на методах, которые извлекают данные, так как метод с любым названием будет отрабатывать одинаково хорошо. Однако для операций обновления, удаления и создания нужно придерживаться определенных правил, основываясь на которых WCF RIA Services ищет и исполняет нужные методы, например, такие как UpdateTask, InsertTask, DeleteTask. Возможно указание нескольких вариантов для каждой операции.
И не забывайте про возможности настройки используя атрибуты. Например для стороны осуществляющей запросы, декорировать методы можно атрибутом [Query], что сделает Ваш код более читабельным и легким для понимания. Нужно помнить, что и тип возвращаемого значения тоже многое говорит о назначении метода. Например, метод возвращающий IQueryable, IEnumberable — однозначно отвечает за извлечение данных. Однако преимущество использования атрибута Query еще в том, что он поддерживает еще некоторые дополнительные параметры, такие как максимальное количество возвращаемых результатов, которые ограничит их количество, даже если из БД вернется после запроса больше необходимого.
Пользовательские доменные службы
А что делать, если Вы не хотите использовать Entity Framework? Как вариант можно воспользоваться LINQ to SQL. Я бы советовал использоваться Entity Framework с новыми проектами. И по возможности со старыми.
LINQ to SQL поддерживается в WCF RIA Services через Toolkit.
Однако многие используют другие стратегии доступа к данным, например nHibernate и другие источники данных, такие как Oracle, MySQL и многие другие. Все это можно так же использовать в WCF RIA Services, но нужно определить объекты данных как простые сущности и использовать их далее в коде как сочтете нужным. Такой подход называется POCO (Plain Old CLR Objects) доменных служб.
Для создания такой доменной службы, класс домена службы нужно наследовать напрямую от DomainService, а не от LinqToEntitiesDomainService. В помощнике создания, кода создаете домен сервиса выберите «Пустой класс службы домена» в выпадающем меню «Доступные классы контекста». Затем определяете сущности, возвращаете коллекции IEnumerable этих сущностей, если Ваш источник данных не поддерживает IQueryable и делайте все, что нужно, в методах на основе источника данных.
Ключ, которым Вы обрамляете свои сущности, определяет, что они должны иметь ключевые свойства, которые однозначно их идентифицируют. Обычно «int» или «Guid». Указываете это свойство как атрибут Wcf ria services что это.
Ниже приведен код, который показывает, как объявлять POCO домен службы и его сущности:
В дополнении к атрибуту Wcf ria services что это, если у Вас имеются свойства, которые сами являются типами сущностей(связанные сущности или объединения), то необходимо добавить свойства к этой сущности, например, ID, которое устанавливает соответствие ключевых полей. Кроме того, непосредственно у свойства сущности необходимо указать атрибут [Association], которое показывает ID свойства, которое устанавливает связи(отношения) и сообщает, что это и есть внешний ключ. У свойства сущности еще нужно указать атрибут [Include], что б дочерняя сущность так же всегда извлекалась, когда извлекается родительская по средству RIA Services.
После запуска проекта получите такое окошко, где можно проводить выборку по дате:
WCF RIA Services. Начало. Часть 1
От переводчика
В данном цикле переводов присутствует хорошая доля, добавленная лично мной, так как в оригинале используется устаревшая VS, а так же пропущены некоторые, на мой взгляд важные моменты, без которых усвоение материала сильно усложняется. Поехали.
Осторожно. Много картинок!
Вступление
Представьте, что Вам необходимо создать серьезное бизнес приложение, клиент которого оперирует множеством данных, распределенных в различных местах, и которые должны каким-то образом собираться. Для реализации такой задачи Вам будет необходимо изучить ряд новых технологий и подходов, написать кучу кода, отладка. А что в итоге? Если грубо — то просто пересылка данных с серверной части приложения в клиентскую и обратно. Ну и работа с БД. А на что бы Вы хотели сфокусироваться в первую очередь? На реализации пересылки данных? Или на логике обработки, манипулирования, представления этих данных? Думаю, Вы выберете второе.
WCF RIA Services предлагает автоматизацию пересылки данных и создания многоуровневых приложения на основе Silverlight, фокусируя внимание разработчика именно на логике работы. Вы пишите только один раз экземпляр серверного кода, а он автоматически переносится и становится доступным на клиентской стороне, без необходимости ручного дублирования или применения других ухищрений со стороны разработчика. Так же на клиенте остаются доступны все серверные возможности, такие как валидация, права доступа и многие др.
В этом цикле статей Вы ознакомитесь с основными возможностями WCF RIA Services, увидите на практике какие преимущества предоставляет использование данного подхода. На диаграме ниже показано, за что именно отвечает WCF RIA Services:
сегодня воспользуемся стандартным, самым простым шаблоном Silverlight. В последующих частях будем наращивать наши знания путем доработки приложения и использования новых методик, тактик и технологий, одними из которых будет паттерн Model-View-ViewModel (MVVM) и модульное тестирование (unit testing).
Задачи, решаемые создаваемым приложением
Просто электронный блокнот, в который можно заносить событие, давать ему название, исполнителя, проект, дату начала и окончания. В общем ничего сложного или необычного, однако хорошее понимание того, ЧТО нужно сделать только облегчит понимание того КАК это сделать в рамках изучаемой технологии.
Изучаемые аспекты WCF RIA Services:
Шаг 1: Создаем Silverlight приложение и ссылку на серверную часть.
Воспользуемся простой БД, которая будет сохранять задания, а также всю сопутствующую информацию. Для этого необходимо будет запустить скрипт TaskManager.sql, находящийся в коне проекта, создать БД и схему, заполнить БД начальными значениями.
Создайте новый проект с именем «TasksManager». Возможность использовать WCF RIA Services присуща любому типу Silverlight приложений. Однако начнем с самого простого и выберем шаблон «Приложение Silverlight».
После нажатия на кнопку ОК, откроется следующее диалоговое окно, в котором необходимо добавить птичку на «Включить службы WCF RIA».
Благодаря ей создадутся необходимые ссылки на серверный проект, появится кодогенерация и остальные функции, описанные ранее.
Нажимаем ОК и ждем создания проекта.
Шаг 2: Создаем Domain Model Entities
Так как WCF RIA Services в основном предназначен для перемещения данных туда/сюда от клиента к серверу и обратно, Вам понадобятся некоторые модели данных данные. Из коробки поддерживается Entity Framework. Однако существует возможность использовать LINQ to SQL в WCF RIA Services Toolkit. Если создать свой доменный сервис, то можно работать с POCO. Сейчас воспользуемся стандартным Entity Framework.
Двойной клик по созданной БД «Database*.mdf». Откроется окно. Выбираем в нем опять «Database*.mdf», правой кнопкой — «Новый запрос». Откроется редактор запросов. Открываем TasksModel.sql, про который уже говорилось и копиреум от туда все, за исключением первых таких строк:
Нажимаем на кнопку «Выполнить». Все. БД заполнена таблицами, а таблица Tasks заполнена данными.
Жмем правой кнопкой мыши по TaskManager.Web и выбираем «Добавить»-«Создать элемент». Выбираем вкладку «Данные» в левом окне, а в правом выбираем «Модель ADO.NET EDM». Даем имя «TasksModel.edmx«.
Добавить. Откроется диалоговое окно Мастер моделей EDM. Выбираем нужную БД, даем имя сущности «TaskManagerEntities» и кликаем Далее.
На следующем шаге выбираем галочкой таблицы. Даем имя модели «TaskManagerModel», а так же ставим галочку на «Формировать имена объектов во множественном или единственном числе»
Вуаля. Теперь у Вас имеется модель данных Entity Framework для всех таблиц в БД. Однако в этом уроке вы будете работать только с таблицей «Task», однако далее таблицы будут добавляться.
Постройте решение, что б убедиться, что все сделано правильно.
После создания EDM — вам должно открыться окно дизайнера.Если оно автоматически не открылось, то двойной клик в Обозревателе решения по TasksModel.edmx. Далее кликаем по пустой области. И переходим в окно свойств. Меняем параметр«Стратегия создания кода» с «Нет» на «По умолчанию». Пересобираем.
Теперь Пришло время создать службу домена.
Шаг 3: Создание Domain Service
Сейчас создадим ядро RIA Services — службу домена. Правой кнопкой на серверной части: TaskManager.Web – «Добавить»-«Создать элемент». Выбираем в левом окне категория «Веб», а справа «Класс DomainService». Даем имя «TasksDomainService«.
После нажатия на кнопку Добавить, переходим в окно настроек службы. Так как сейчас будем работать только с таблицей Tasks — выбираем ее. В столбце «Включить редактирование» галочка не нужна. Пока. Если ее поставить то получите набор CRUD. Если нет – то только Get (чтение). Жмем ОК.
Созданный код, без коментариев будет выглядеть так:
Класс LinqToEntitiesDomainService предоставляет связь между моделью EDM и службами WCF RIA. Атрибут «EnableClientAccess» указывает на то, что этот метод необходимо добавить в клиентскую часть во время автоматической кодогенерации. В данном случае получили только метод чтения данных из таблицы, однако можно реализовать полноценный CRUD или любые другие действия над данными, которые Вам будут нужны, и которые в итоге так же будут доступны в клиентском проекте. Как это делать рассмотрим более подробно в следующих статьях.
Так же запомните, что используются конвенции, которые относятся к типу возвращаемого значения(Queryable) и правилам именования(GetName). В данном случае имеем делегированную сущность модели данных ObjectContext, которая создается как часть базового класса и используется для извлечения всей таблицы Tasks. Вы так же можете усовершенствовать данный запрос добавив сортировку, фильтры и т.д., однако пока возвращаемое значение имеет тип IQueryable, WCF RIA Services понимает это и формирует соответствующие методы, которые позволят использовать данный функционал на стороне клиента.
Перестроим проект, чтоб убедиться, что все сделано правильно. В клиентском проекте, при нажатии на иконку двух листиков «Показать все файлы» — должен появиться файл с именем TaskManager.Web.g.cs, который и содержит сгенерированный код для клиента.
Шаг 4: Получение данных в UI используя DomainDataSource
Сегодня воспользуемся такой возможность WCF RIA Services, как «drag and drop», используя DomainDataSource непосредственно в UI. В следующих частях рассмотрим так же паттерн MVVM, как его использовать в WCF RIA, а так же как при таком подходе использовать DomainDataSource.
Итак, откройте MainPage.xaml. Далее откройте окно Источники данных. А теперь перетащите Tasks в графический редактор страницы на белое поле. Поправьте размещение. Все. В разделе XAML увидите созданный код для элемента Grid.
Строим и запускаем приложение. И наслаждаемся похожим видом: