Silverlight 3: Отображение данных SQL Server
ОГЛАВЛЕНИЕ
Silverlight 3, несомненно, превосходная технология для веб-программирования. Данная статья рассматривает отображение данных из базы данных SQL Server в приложении Silverlight 3.
• Скачать исходный код - 0.99 Мб
Введение
В настоящем примере используются три технологии: SQL Server, основа связи Windows (WCF) и Silverlight 3, работающий в Visual Studio 2008.
Справка
Есть много прекрасных статей по данной теме, например:
• Блог Скотта Гутрие: Комплексное руководство по Silverlight 2
• Статья Шивпрасада Койралы: 7 простых шагов по подключению к SQL Server с помощью WCF из Silverlight
Были проработаны некоторые из найденных статей, но возник ряд трудностей с некоторыми не полностью понятными областями. Было решено опубликовать данную статью, чтобы представить другой взгляд и добавить больше деталей по вопросу, чтобы помочь начинающему разработчику Silverlight. Были отражены все детали и представлен пошаговый пример.
Установка
Прежде чем начать, установите следующее:
- SQL Server
На компьютере должен быть установлен SQL Server или SQL Express. Так как вы уже начали читать статью, наверное, так и есть. Но если нет – смотрите по следующей ссылке инструкции по загрузке и установке SQL Express.
- База данных AdventureWorks
Надо скачать базу данных AdventureWorks и установить ее в SQL Server. Инструкции, как сделать это, смотрите по ссылке.
- Silverlight 3
Кроме того, надо установить Silverlight 3. Silverlight 3 работает внутри Visual Studio 2008. Чтобы установить Silverlight 3, посетите следующую ссылку.
Создание проекта
Для начала запустите Visual Studio 2008 и создайте новый проект (меню Файл | Новый | Проект…).
В древовидном меню “Типы проекта” слева, под узлом Visual Basic, щелкните по узлу Silverlight, далее выберите шаблон “Приложение Silverlight” справа. Назовите проект “AdventureWorks”. Убедитесь, что выбран .NET Framework 3.5. Нажмите OK, когда закончите.
Окно создания проекта выглядит так:
После нажатия кнопки OK откроется окно “Новое приложение Silverlight”. В нем укажут, что выбрать: создан новый проект веб-сайта ASP.NET или проект веб-приложения ASP.NET, размещающего в себе приложение Silverlight. Оставляется выбранным “Проект веб-приложения ASP.NET”, но меняется имя нового веб-проекта с “AdventureWorks.Web” на “AdventureWorks_WebServer” для большей ясности. Нажмите кнопку OK, когда закончите.
Так выглядит окно выбора типа проекта:
После нажатия кнопки OK Visual Studio создаст решение, размещающее в себе приложение веб-сервера ASP.NET “AdventureWorks_WebServer”, служащее тестовой средой для клиентского приложения Silverlight “AdventureWorks”, которое тоже было создано.
Проводник решения покажет следующее:
В клиентском приложении Silverlight AdventureWorks есть два файла .xaml: файл App.xaml, объявляющий ресурсы, и файл MainPage.xaml, являющийся стандартным пользовательским управляющим элементом, загружающимся при запуске приложения. Файл MainPage.xaml позже будет использован для проектирования интерфейса.
В приложении AdventureWorks_WebServer любой из следующий четырех файлов может разместить в себе приложение Silverlight:
• AdventureWorksTestPage.aspx
• AdventureWorksTestPage.html
• Default.aspx
• Silverlight.js
Файл AdventureWorksTestPage.aspx является страницей запуска по умолчанию, загружаемой при запуске приложения, которая разместит в себе пользовательский управляющий элемент MainPage.xaml.
Файл AdventureWorksTestPage.html, файл Default.aspx и файл Silverlight.js можно удалить из примера, так как они не будут использоваться.
Файл Web.config хранит конфигурационные данные для веб-сервера. Подробнее он изучается далее.
Создание подключения AdventureWorks
Если уже установлен SQL Server и прикреплена база данных AdventureWorks, то пора создать подключение.
В Visual Studio щелкните по меню ”Инструменты | Подключиться к базе данных”… Откроется окно “Добавить подключение для создания конфигурации”. Убедитесь, что источник данных установлен в Microsoft SQL Server (SqlClient). Установите имя сервера в “localhost” - если база данных прикреплена к SQL Server, или “localhost\SQLExpress” – если база данных прикреплена к SQL Express (если имя экземпляра изменено на нечто отличное от стандартного, то обязательно укажите это вместо “SQLExpress”). Наконец, выберите базу данных “AdventureWorks”. Нажмите кнопку OK, когда закончите.
Так выглядит окно добавления подключения:
После создания подключения будет создан класс LINQ для SQL и сконфигурирован на использование базы данных AdventureWorks.
Добавление классов LINQ для SQL
Так как было создано подключение к базе данных AdventureWorks SQL Server в проводнике сервера, будет добавлен класс LINQ для SQL, хранящий информацию о подключении и извлекающий данные из таблицы Person.Contact.
Чтобы выполнить этот шаг, щелкните правой кнопкой мыши по проекту AdventureWorks_WebServer, затем выберите “Добавить | Новый элемент”… Когда откроется окно “Добавить новый элемент”, щелкните по узлу “Данные”, далее выберите “Шаблон классов LINQ для SQL” справа. Оставьте имя как “DataClasses1.dmbl”, далее нажмите кнопку “Добавить”.
Пример показан ниже:
После нажатия кнопки “Добавить” файл “DataClasses1.dbml” будет добавлен в проект AdventureWorks_WebServer и будет виден в проводнике решения. Если он не открылся автоматически, дважды щелкните по нему, чтобы открыть проектировщик.
Далее убедитесь, что проводник сервера открыт (Меню Вид | Проводник сервера). Разверните узел базы данных AdventureWorks и разверните узел “Таблицы”. Найдите таблицу “Контакт (человек)”, щелкните левой кнопкой мыши по ней, затем перетащите ее из проводника сервера в проектировщик DataClasses1.dbml следующим образом:
После успешного добавления таблицы контактов в DataClasses1.dbml сохраните проект (Меню Файл | Сохранить все). Теперь закройте проектировщик DataClasses1.dbml, потому что с ним закончено.
Добавление класса ContactRecord
Просмотр таблицы контактов выше говорит, что в ней есть много информации, много столбцов вроде: ContactID, NameStyle, Title и т. д. Поскольку нужны только столбцы FirstName, LastName и EmailAddress, будет создан пользовательский класс ContactRecord, представляющий каждую строку контакта из таблицы, вместо использования предоставляемого типа Contact.
В качестве замечания, почему бы не использовать ADO.NET? С DataSets и DataTables гораздо легче работать! Хотя это верно, WCF был спроектирован в соответствии с принципами SOA(сервис-ориентированная архитектура), а значит, надо программировать на контрактах, а не реализации. Поскольку DataSets и DataTables являются специфичными для .NET типами, их нельзя использовать. Несмотря на то, что их можно использовать внутри службы WCF, их нельзя передать Silverlight.
Чтобы создать класс ContactRecord, щелкните правой кнопкой мыши по узлу проекта AdventureWorks_WebServer в проводнике решения, выберите “Добавить | Класс…“ Назовите его “ContactRecord.vb”, потом нажмите кнопку “Добавить“.
После добавления класса добавьте в него три открытых члена: FirstName, LastName и Email. Теперь класс должен выглядеть так:
Public Class ContactRecord
Public FirstName As String
Public LastName As String
Public Email As String
End Class
Сохраните проект (Меню Файл | Сохранить все). Далее будет рассмотрено добавление службы WCF.
Добавление WCF
После установки класса LINQ для SQL и создания класса ContactRecord пора добавить класс основы связи Windows в проект AdventureWorks_WebServer. Этот класс будет играть роль службы, использующей класс LINQ для SQL для извлечения данных из базы данных AdventureWorks и возврата их в клиентское приложение Silverlight.
В проводнике решения щелкните правой кнопкой мыши по узлу проекта AdventureWorks_WebServer и выберите “Добавить | Новый элемент…“ Щелкните по узлу Silverlight, потом выберите шаблон службы WCF с поддержкой Silverlight. Оставьте имя “Service1.svc” и нажмите кнопку “Добавить“.
Так выглядит окно добавления шаблона службы WCF:
После добавления службы WCF файл “Service1.svc” добавится в узел проекта AdventureWorks_WebServer в проводнике решения. Если он не открылся автоматически, дважды щелкните по нему, чтобы открыть окно кода.
Окно кода должно выглядеть так:
Imports System.ServiceModel
Imports System.ServiceModel.Activation
<ServiceContract(Namespace:="")> _
<AspNetCompatibilityRequirements( _
RequirementsMode:= _
AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Service1
<OperationContract()> _
Public Sub DoWork()
' Добавить сюда реализацию операции
End Sub
' Добавить сюда больше операций и пометить их
' <OperationContract()>
End Class
Со службой будет сделана пара вещей:
• Добавить пространство имен в ServiceContract. Это обеспечит уникальность пользовательских типов.
Пространство имен должно быть URI, но не обязательно указывающее на реальное место в интернете. Оно служит лишь уникальным идентификатором для пользовательского типа.
• Удалить весь код и комментарии внутри класса.
Добавить функцию GetContacts
Надо добавить собственную функцию GetContacts(), вызываемую из клиентского приложения Silverlight. При добавлении этой функции объявите возвращаемый тип как List(Of ContactRecord) и обязательно добавьте атрибут <OperationContract()> прямо над именем функции. Это сделает данную функцию доступной для клиента Silverlight.
После добавления пространства имен и функции GetContactions() окно кода должно выглядеть так:
Imports System.ServiceModel
Imports System.ServiceModel.Activation
<ServiceContract(Namespace:="http://adventureworks.com/")> _
<AspNetCompatibilityRequirements( _
RequirementsMode:= _
AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class Service1
<OperationContract()> _
Public Function GetContacts() _
As List(Of ContactRecord)
End Function
End Class
Добавить код в функцию GetContacts
Внутри функции GetContacts() можно использовать добавленный класс LINQ для SQL “DataClasses1.dbml” и, разумеется, LINQ, для доступа к данным в таблице контактов базы данных AdventureWorks. В список добавляются первые 1000 строк, и список возвращается.
Так выглядит функция:
<OperationContract()> _
Public Function GetContacts() As List(Of ContactRecord)
'Использовать класс LINQ для SQL для доступа к
' таблице контактов в базе данных Adventure-
' Works.
Dim db As New DataClasses1DataContext()
'Использовать LINQ для извлечения строк из
' таблицы контактов.
' Метод ".Take(1000)"
' возвращает первые (верхние) 1000 строк
' из набора результатов.
Dim contacts = _
(From contact _
In db.Contacts _
Order By contact.FirstName, _
contact.LastName _
Select contact).Take(1000)
'Создать новый обобщенный список типа запись
' контакта. Этот список будет
' возвращен клиентскому приложению Silverlight
'
Dim list As New List(Of ContactRecord)
'Обойти в цикле каждую строку таблицы
'контактов и добавить ее в список.
For Each c In contacts
list.Add( _
New ContactRecord With _
{.FirstName = c.FirstName, _
.LastName = c.LastName, _
.Email = c.EmailAddress})
Next
'Вернуть список
Return list
End Function
Далее сохраните проект (Меню Файл | Сохранить все).
Обновление файла Web.config
Добавленная служба WCF использует файл Web.config для доступа к конфигурационным данным. Конфигурационные данные, которые ей надо извлечь, включают в себя адрес, привязку и контракт, находящиеся в теге <endpoint>.
Найдите файл “Web.config” в проводнике решения и дважды щелкните по нему, чтобы открыть. Открыв его, прокрутите донизу и найдите раздел <services>. Так выглядит раздел службы из файла web.config:
<service behaviorConfiguration=
"AdventureWorks_WebServer.Service1Behavior"
name="AdventureWorks_WebServer.Service1">
<endpoint address="" binding="customBinding"
bindingConfiguration="customBinding0"
contract="AdventureWorks_WebServer.Service1" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
Есть два тега endpoint: верхний, содержащий address=””, и нижний, содержащий address=”mex”. Надо обратить внимание на верхний с address=”” следующим образом:
<endpoint address="" binding="customBinding"
bindingConfiguration="customBinding0"
contract="AdventureWorks_WebServer.Service1" />
Чтобы успешно общаться с клиентским приложением Silverlight, надо изменить привязку на “basicHttpBinding” и удалить bindingConfiguration, как указано ниже:
<endpoint address="" binding="basicHttpBinding"
contract="AdventureWorks_WebServer.Service1" />
Произведя эти изменения, сохраните проект (Меню Файл | Сохранить все), затем закройте файл web.config.
Теперь подключение установлено, добавлен класс LINQ для SQL, создан класс ContactRecord, запрограммирована служба WCF, и обновлен файл web.config… Пора начать работать с интерфейсом клиента Silverlight.
Добавление ссылки на службу в клиент Silverlight
Начинается работа с самим Silverlight 3.
Откройте проводник решения и перейдите к клиентскому приложению Silverlight AdventureWorks, как показано тут:
Сначала надо добавить ссылку на созданную ранее службу WCF. Это позволит клиентскому приложению Silverlight общаться с ранее созданной службой WCF. Чтобы сделать это, щелкните правой кнопкой мыши по узлу проекта AdventureWorks, потом выберите “Добавить ссылку на службу…”, следующим образом:
При нажатии на пункт меню откроется окно “Добавить ссылку на службу“. После этого проделайте следующие шаги:
• Нажмите кнопку “Найти“, чтобы найти адрес службы.
• В древовидном меню Службы увидите появившуюся в списке службу.
• Разверните узел “Service1.svc”.
• Разверните узел “Service1”.
• Щелкните по конечному дочернему узлу “Service1”.
• Метод “GetContacts” отобразится в списке Операции справа.
Окно выглядит так:
Если после нажатия кнопки “Найти“ служба Service1.svc не появилась в списке, вернитесь к файлу web.config и убедитесь, что он сконфигурирован правильно, как показано выше. Обязательно удалите все лишние пробелы между атрибутами address, binding и contract и их значениями.
Далее нажмите кнопку “Дополнительно…“, чтобы отобразилось окно “Настройки ссылки на службу“. В нем надо изменить тип коллекции на System.Collections.Generic.List следующим образом:
После изменения типа коллекции нажмите кнопку OK, чтобы закрыть окно “Настройки ссылки на службу“, затем снова нажмите OK, чтобы закрыть окно “Добавить ссылку на службу“.
Теперь добавленная новая ссылка на службу появится в проводнике решения:
Ссылка на службу будет использована позже.
Программирование интерфейса
Теперь все на месте! Осталось запрограммировать интерфейс клиентского приложения Silverlight и добавить код на Visual Basic, извлекающий данные, и отобразить их в интерфейсе.
В проводнике решения найдите файл MainPage.xaml и дважды щелкните по нему для открытия файла в редакторе XAML.
Открыв файл MainPage.xaml в редакторе XAML, вы заметите, что он является пользовательским управляющим элементом. Это очевидно из начального и конечного тегов <UserControl>. Как сказано ранее, AdventureWorksTestPage.aspx является веб-страницей запуска, загружаемой при запуске приложения, но в нее встроен пользовательский управляющий элемент MainPage.xaml. Интерфейс, программируемый в пользовательском управляющем элементе MainPage.xaml, является реальным интерфейсом, появляющимся на веб-странице при запуске программы.
Конфигурирование главной сетки
Сначала надо найти тег <Grid и добавить атрибут Margin, присвоив ему значение 10. Это создаст рамку в 10 вокруг всех четырех сторон пользовательского управляющего элемента. Установите ShowGridLines=”True”, чтобы линии сетки были видны при программировании интерфейса. Это будет удалено позже, но пока позволит видеть сетку по мере работы.
<Grid x:Name="LayoutRoot"
Margin="10" ShowGridLines="True" >
</Grid>
Затем надо разбить интерфейс на два раздела: раздел шапки вверху и раздел данных, заполняющий остальную страницу. Чтобы сделать это, сконфигурируйте Grid так, чтобы она имела один столбец и две строки:
<Grid x:Name="LayoutRoot"
Margin="10" ShowGridLines="True" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
Звездочка (“*”) указывает оставшееся свободное пространство. Это заставит ширину столбца автоматически подстраиваться под ширину Grid. Теперь запустите приложение (F5). Так как приложение запущено впервые, предложат включить отладку, когда откроется следующее окно:
Оставьте выбранный по умолчанию пункт и нажмите кнопку OK.
Как только приложение запустится и загрузится веб-страница, можно будет увидеть, как веб-страница разделена на два отдельных раздела: шапка вверху и раздел данных, заполняющий остальную страницу. Страница выглядит так:
Закройте Internet Explorer и вернитесь в редактор MainPage.xaml. Удалите ShowGridLines=”True” из тега Grid.
Сконфигурировать сетку шапки
В раздел шапки главной сетки (строка 0) будет добавлена другая сетка, устанавливающая заголовок страницы и кнопку, извлекающую и загружающую данные.
Прежде чем добавить сетку, добавьте приятную темно-красную рамку толщиной “1”. Эта рамка будет охватывать сетку.
<Border BorderBrush="Maroon" BorderThickness="1" >
</Border>
Добавьте сетку внутри тегов Border и задайте бледно-желтый цвет фона. Добавьте расширенные атрибуты к сетке, приказывающие ей разместиться в разделе шапки (первый столбец (столбец 0); верхняя строка (строка 0)) главной сетки.
<Border BorderBrush="Maroon" BorderThickness="1" >
<Grid Background="LightYellow" Grid.Column="0" Grid.Row="0" >
</Grid>
</Border>
Определите два столбца для сетки: Первый столбец будет иметь ширину “*” и будет хранить заголовок. Второй столбец будет иметь ширину “100” и будет хранить кнопку, загружающую данные.
<Border BorderBrush="Maroon" BorderThickness="1" >
<Grid Background="LightYellow" Grid.Column="0" Grid.Row="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
</Grid>
</Border>
Добавьте TextBlock для отображения заголовка страницы. Установите Text в “Контакты AdventureWorks”. С помощью расширенных атрибутов сетки разместите TextBlock в столбце 0, строке 0.
Далее добавьте Button, служащую для отображения данных. Установите ее Name в btnLoad, Content в “Загрузить”, и с помощью расширенных атрибутов сетки разместите Button в столбце 1, строке 0. Установите атрибут Click в “btnLoad_Click”.
<Border BorderBrush="Maroon" BorderThickness="1" >
<Grid Background="LightYellow" Grid.Column="0" Grid.Row="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Padding="10,0,0,0"
VerticalAlignment="Center"
Text="AdventureWorks Contacts"
FontSize="28"
Foreground="Maroon"
Grid.Row="0" Grid.Column="0" />
<Button x:Name="btnLoad" Content="Load"
VerticalAlignment="Center"
Margin="10"
Grid.Row="0" Grid.Column="1"
Click="btnLoad_Click"/>
</Grid>
</Border>
Вот и конец шапки! Прежде чем идти дальше, найдите атрибут Click кнопки Button и щелкните правой кнопкой мыши по “btnLoad_Click”, затем выберите “Перейти к обработчику события”, чтобы создать соответствующую подпрограмму. После создания подпрограммы вернитесь в редактор XAML.
Сконфигурировать сетку данных
Надо добавить DataGrid Silverlight к интерфейсу. Чтобы сделать это, отобразите панель инструментов, найдите управляющий элемент DataGrid, перетащите его в редактор XAML и опустите его сразу под тегом </Border>.
Установите Name в “dataGrid1”; AutoGenerateColumns в “False”, потому что столбцы будут добавляться вручную; Visibility в “Collapsed”, потому что сетка должна быть скрыта при загрузке страницы; и потом с помощью расширенных атрибутов главной сетки разместите DataGrid в столбце 0, строке 1 (являющейся нижней частью главной сетки).
<data:DataGrid x:Name="dataGrid1"
AutoGenerateColumns="False"
Visibility="Collapsed"
Grid.Row="1" Grid.Column="0" >
</data:DataGrid>
Теперь надо добавить к DataGrid три текстовых столбца: один для имени, один для фамилии, и один для электронной почты.
Каждый столбец привязывается к источнику данных путем установки атрибута Binding. Значением атрибута Binding является строковое выражение, заключенное в фигурные скобки {}, использующее ключевое слово Binding и имя свойства в источнике данных, к которому привязывается.
<data:DataGrid x:Name="dataGrid1"
AutoGenerateColumns="False"
Visibility="Collapsed"
Grid.Row="1" Grid.Column="0" >
<data:DataGrid.Columns>
<data:DataGridTextColumn
Binding="{Binding FirstName}"
Header="First Name" />
<data:DataGridTextColumn
Binding="{Binding LastName}"
Header="Last Name" />
<data:DataGridTextColumn
Binding="{Binding Email}"
Header="Email Address" />
</data:DataGrid.Columns>
</data:DataGrid>
Сохраните проект (Меню Файл | Сохранить все). Потом запустите приложение (F5). Конечный результат должен выглядеть так:
Закройте Internet Explorer и вернитесь в редактор XAML, когда закончите.
Добавление кода Visual Basic
Осталось добавить код Visual Basic, чтобы связать все вместе и заставить работать. Щелкните правой кнопкой мыши по редактору XAML и выберите “Просмотреть код”, чтобы перейти в окно кода.
Вверху окна кода с помощью ключевого слова WithEvents добавьте объявление службы WCF:
'Создать новый экземпляр службы WCF
Private WithEvents mService As New ServiceReference1.Service1Client()
Перейдите к выпадающему списку Имя класса вверху окна кода и выберите “mService”; далее перейдите к выпадающему списку Имя метода вверху окна кода и выберите “GetContactsCompleted”.
Выбор “GetContactsCompleted” из выпадающего списка имя метода создаст обработчик события mService_GetContactsCompleted. Внутри этого обработчика события добавьте всего две строки кода: одну для загрузки DataGrid с данными, и одну, делающую сетку видимой:
Private Sub mService_GetContactsCompleted( _
ByVal sender As Object, _
ByVal e As ServiceReference1 _
.GetContactsCompletedEventArgs) _
Handles mService.GetContactsCompleted
dataGrid1.ItemsSource = e.Result
dataGrid1.Visibility = Windows.Visibility.Visible
End Sub
Обработчик события GetContactsCompleted выполняется после того, как служба WCF извлекла данные из SQL Server и готова передать данные клиенту Silverlight.
Добавьте код, запускающий асинхронный процесс получения данных контакта из службы WCF. Добавьте эту одну строку кода в обработчик события btnLoad_Click:
Private Sub btnLoad_Click( _
ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
mService.GetContactsAsync()
End Sub
Полное окно кода должно выглядеть так:
Partial Public Class MainPage
Inherits UserControl
'Создать новый экземпляр службы WCF
Private WithEvents mService As New ServiceReference1.Service1Client()
Public Sub New()
InitializeComponent()
End Sub
Private Sub btnLoad_Click( _
ByVal sender As System.Object, _
ByVal e As System.Windows.RoutedEventArgs)
mService.GetContactsAsync()
End Sub
Private Sub mService_GetContactsCompleted( _
ByVal sender As Object, _
ByVal e As ServiceReference1 _
.GetContactsCompletedEventArgs) _
Handles mService.GetContactsCompleted
dataGrid1.ItemsSource = e.Result
dataGrid1.Visibility = Windows.Visibility.Visible
End Sub
End Class
Вот и все!
Сохраните проект (Меню Файл | Сохранить все). Потом запустите приложение (F5). Когда приложение откроется, нажмите кнопку “Загрузить”, чтобы извлечь данные из базы данных AdventureWorks SQL Server, и загрузить их в сетку данных Silverlight. Если все сработало правильно, отобразится следующее:
Заключение
Статья показала, как создать службу WCF, использующую LINQ для SQL для извлечения данных из таблицы Person.Contact базы данных AdventureWorks, как обновить конфигурацию конечной точки службы файла web.config, чтобы дать возможность службе WCF вернуть результаты клиентскому приложению Silverlight, а также как сослаться на службу WCF из клиентского приложения Silverlight, и как запрограммировать интерфейс клиента Silverlight для отображения извлеченных данных в сетке данных Silverlight.