SharePoint Business Connectivity Services: Новые возможности
Опубликовано: 23 марта, 2010 Filed under: Uncategorized | Tags: BCS, BDC, sharepoint, SharePoint Designer, SQL Server, visual studio, WCF 1 комментарийЗаписал скринкаст по Business Connectivity Services.
- Принципы построения интеграционных решений на SharePoint
- Работа с внешними данными
- Демонстрация возможностей SharePoint BCS.
- Обсуждение принципов работы, дистрибуции и потенциала платформы.
- Демонстрация примеров работы с сервисом.
SharePoint 2010: Примеры работы с BCS
Опубликовано: 31 января, 2010 Filed under: BCS, sharepoint, SharePoint 2010 | Tags: BCS, SharePoint 2010, WCF, Web Service Оставьте комментарийВведение
Предлагаю рассмотреть несколько примеров работы с SharePoint 2010 Business Connectivity Services.
Все ресурсы, связанные с Business Connectivity Services можно найти на Business Connectivity Services Resource Center. Кстати на нём же можно скачать замечательный постер-шпаргалку по технологии.
Для работы с рассматриваемыми примерами предлагаю вам скачать SharePoint 2010 SDK.
Adventure Works Web Service
В данном примере показана реализация стандартного asp.net asmx сервиса, ориентированного на работу с BCS. Этот сервис представляет доступ к данным из SQL Server. С помощью LINQ to SQL реализовано объектно-реляционное преобразование.
Вы наверняка согласитесь с утверждением, что при прочих равных условиях asmx сервисы создаются намного проще WCF сервисов
Для работы с ним понадобится sample database с соответствующим названием “AdventureWorks”.
Примеры баз данных (таких как AdventureWorks) для основных версий SQL Server, а так же решений для них, теперь централизованны и хранятся на CodePlex: http://msftdbprodsamples.codeplex.com/
Сервис WebService.asmx предоставляет ряд методов для стандартных операций взаимодействия с данными (Create, Read, Update, Delete).
Для наглядности предметной области основные сущности определены в виде POCO классов, к примеру:
public class SalesCustomer { public int CustomerId { get; set; } public String Title { get; set; } public String FirstName { get; set; } public String MiddleName { get; set; } public String LastName { get; set; } public String EmailAddress { get; set; } public String Phone { get; set; } public DateTime ModifiedDate { get; set; } }
Классы же, генерируемые LINQ to SQL используются по назначению, т.е. в качестве DataModel, которая в последствии отображается на модель предметной области. Хоть пример и учебный, было очень приятно, что он имеет довольно таки логичное и обоснованное применение технологий по назначению.
Предметная область в данном случае состоит из 3 основных сущностей:
- SalesCustomer
- SalesOrderDetail
- SalesOrderHeader
Причём дизайн данных сущностей ориентирован на работу с BCS, это можно проследить по построению ассоциаций между сущностями не по ссылке, а по идентификатору. К примеру, связь между SalesCostumer и SalesOrderHeader:
public class SalesOrderHeader { public int CustomerID { get; set; } … }
Здесь стоит пояснить механизм работы с ассоциациями в BCS. Ассоциации в BCS – основной механизм связи нескольких “внешних типов содержимого”. Для его реализации используются так называемые Association Methods. По организации работы принцип вторит тому, что применяется в реляционных базах данных для реализации отношений, т.е. через доступ по внешнему ключу (Foreign Key).
В связи с данными особенностями в сервисе определяются специализированные методы, например этот:
[WebMethod] public SalesOrderHeader[] GetOrdersForCustomer(int customerId) { List<SalesOrderHeader> salesOrderHeaders = new List<SalesOrderHeader>(); Adventureworks.SalesOrderHeader[] sohArr = (from soh in dataContext.SalesOrderHeaders where soh.CustomerID == customerId select soh).ToArray(); PopulateSalesOrderHeader(salesOrderHeaders, sohArr); return salesOrderHeaders.ToArray(); }
Данные методы в дальнейшем будут привязаны к BCS Associations Methods, которые и будут работать для связанных сущностей.
Представленный веб-сервис следует опубликовать в IIS.
Далее, воспользовавшись SharePoint Designer 2010 создать и опубликовать BDC Model:
- Открыть в SharePoint Designer 2010 интересующий вас узел
- Перейти в секцию External Content Types
- Создать новый “внешний тип содержимого”
- В качестве источника данных выбрать WCF Service
- Указать URL подключения и тип соединения
- С помощью мастера произвести отображение всех необходимых веб-методов на методы BDС Model
- Сохранить внешний тип содержимого
Данный процесс наглядно описан в SDK http://msdn.microsoft.com/en-us/library/ee556431(office.14).aspx
Пример файла, описывающего BDC Model<?xml version="1.0" encoding="utf-8" standalone="yes"?> <Model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog BDCMetadata.xsd" Name="AdventureWorksWSModel" IsCached="false" xmlns="http://schemas.microsoft.com/windows/2007/BusinessDataCatalog"> <LobSystems> <LobSystem Type="Wcf" Name="AdventureWorksWS"> <Properties> <Property Name="WsdlFetchAuthenticationMode" Type="System.String">PassThrough</Property> <Property Name="WcfMexDiscoMode" Type="System.String">Disco</Property> <Property Name="WcfMexDocumentUrl" Type="System.String">http://webserver:90/webservice.asmx?wsdl</Property> <Property Name="WcfProxyNamespace" Type="System.String">BCSServiceProxy</Property> <Property Name="WildcardCharacter" Type="System.String">*</Property> </Properties> <LobSystemInstances> <LobSystemInstance Name="AdventureWorksWS"> <Properties> <Property Name="WcfAuthenticationMode" Type="System.String">PassThrough</Property> <Property Name="WcfEndpointAddress" Type="System.String">http://webserver:90/webservice.asmx</Property> <Property Name="ShowInSearchUI" Type="System.String"></Property> </Properties> </LobSystemInstance> </LobSystemInstances> <Entities> <Entity Namespace="AdventureWorks” Version="1.0.0.0" EstimatedInstanceCount="10000" Name="WSCustomer" DefaultDisplayName="WSCustomer"> <Properties> <Property Name="OutlookItemType" Type="System.String">Contact</Property> </Properties> <Identifiers> <Identifier TypeName="System.Int32" Name="CustomerId" /> </Identifiers> <Methods> <Method IsStatic="false" Name="GetCustomerById"> <Parameters> <Parameter Direction="In" Name="customerId"> <TypeDescriptor TypeName="System.Int32" IdentifierName="CustomerId" Name="customerId" /> </Parameter> <Parameter Direction="Return" Name="GetCustomerById"> <TypeDescriptor TypeName="BCSServiceProxy.SalesCustomer, AdventureWorksWS" Name="GetCustomerById"> <TypeDescriptors> <TypeDescriptor TypeName="System.Int32" ReadOnly="true" IdentifierName="CustomerId" Name="CustomerId" /> <TypeDescriptor TypeName="System.String" Name="Title" /> <TypeDescriptor TypeName="System.String" Name="FirstName"> <Properties> <Property Name="OfficeProperty" Type="System.String">FirstName</Property> </Properties> </TypeDescriptor> <TypeDescriptor TypeName="System.String" Name="MiddleName" /> <TypeDescriptor TypeName="System.String" Name="LastName"> <Properties> <Property Name="OfficeProperty" Type="System.String">LastName</Property> </Properties> </TypeDescriptor> <TypeDescriptor TypeName="System.String" Name="EmailAddress" /> <TypeDescriptor TypeName="System.String" Name="Phone" /> <TypeDescriptor TypeName="System.DateTime" Name="ModifiedDate" /> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Type="SpecificFinder" ReturnParameterName="GetCustomerById" Default="true" Name="GetCustomerById" DefaultDisplayName="Read Item WSCustomer"> <Properties> <Property Name="LastDesignedOfficeItemType" Type="System.String">Contact</Property> </Properties> </MethodInstance> </MethodInstances> </Method> </Methods> </Entity> </Entities> </LobSystem> </LobSystems> </Model>
AdventureWorksDll
Данный пример ориентирован на подключение .NET типа в качестве источника данных для внешнего типа содержимого. Фактически пример не отличается от предыдущего. Принципиальная разница состоит в том, что в данном случае сборка должна находится локально по отношению к установленному SharePoint. Все принципы дизайна методов доступа сохранены.
Кстати, данный пример практически ничем не уступает в поддержке актуальности варианту с веб-сервисом, т.к. современные методы дистрибуции .NET решений (к примеру ClickOnce) позволяют поддерживать в актуальном состоянии решение у большого количества клиентов.
Так что же происходит в BCS при работе с веб-сервисами
Механизм вполне логичен и является стандартным во многих ситуациях. Запрашивается URL, который указан в качестве адреса сервиса. На основе полученной схемы (как правило в SOAP это WSDL). Далее происходит самое интересное, в рантайме генерятся прокси-объекты для доступа к данным. Данные объекты компилируются в памяти и кэшируются для дальнейших вызовов.
Custom Connector
Кроме подключения к .NET типу, так же существует возможность реализации “своего коннектора”. В чём же принципиальная разница? В том, что коннектор является свободной абстракцией над источником данных. Т.е. подразумевается его настройка пользователем, к примеру, в SharePoint Designer’e, в отличии от .NET типа, который будет отражаться на конкретный “внешний тип содержимого”. Подробнее можно узнать здесь: http://msdn.microsoft.com/en-us/library/ee554911(office.14).aspx
BCS Cache
В заключение хочу немного рассказать о способах оптимизации ваших решений на основе BCS.
В BCS существует мощных механизм кэширования. Реализуется он на основе так называемых Cache Description. Описываются они в XML файле subscription.xml и должны располагаться в папке вместе в XML описанием BDC Model. С помощью можно описывать правила кеширования определенных методов, определенных сущностей (по их идентификатору), а так же связанных сущностей.
Так выглядит Cache Description
<?xml version="1.0" encoding="utf-8"?> <Subscription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="CustomerQuery Item List" IsCached="true" EntityName="Customer" EntityNamespace="http://example.com" RefreshIntervalInMinutes="60" View="CustomerRead Item" LobSystemInstanceName="AdventureWorks" xmlns="http://schemas.microsoft.com/office/2006/03/BusinessDataCatalog"> <Queries> <Query Name="27aa2ba2-fd5f-452c-87bb-24cf505f6071" IsCached="true" RefreshIntervalInMinutes="60" MethodInstanceName="CustomerQuery Item List" Enabled="false" /> </Queries> </Subscription>
Подробнее о кэшировании можно узнать здесь: http://msdn.microsoft.com/en-us/library/ee556385(office.14).aspx