Академический Документы
Профессиональный Документы
Культура Документы
ne of the most outstanding new features available in the MOSS Enterprise Edition is called the Business Data Catalog (BDC). The BDC is a subject worthy of its own special chapter because it fills in a huge part of the overall enterprise information architecture by providing the ability to incorporate enterprise data with and into SharePoint. While the Enterprise Edition does cost more, the BDC, Excel Services, InfoPath Forms Services, and KPI Tools it includes might pay off quickly. In a collaborative environment, SharePoint plays a pivotal role since it can store, manage, and search much of the information used on a day-to-day basis. When used for what it does well, SharePoint brings to the surface much of the information and resources that were once silos on desktops and laptopshowever, it is self-contained. The BDC completes the information architecture, because it allows SharePoint to marry itself to enterprise data sources and combine its data with other systems. The BDC enables SharePoint to reach out into other enterprise systems and data sources and use the data in views or pull actual data into SharePoint. In addition, data sources defined within the BDC become part of SharePoint and make the backend data searchable. Using the BDC, the complete picture of an entity can be created; the information from nearly any backend system can now be combined with documents, calendars, and project plans, and all of it can be searched. The capabilities of the BDC have also been extended into the SharePoint User Profiles. By default, user profiles are created from Active Directory data (or other authentication sources) and combined with SharePoint specific system and user-defined properties. However, in many large environments, the authentication source is usually not the real source of user information; it is usually stored in an HR system like PeopleSoft. This is particularly important regarding personnel movements, new hires, and terminations; the most accurate data is usually tied to the paycheck and not to the system login. The BDC provides an extension (or connector) that allows this data to be pulled directly into SharePoints User Profiles, meaning that more accurate data and less user intervention are required. Some of what the BDCs functionality enables in SharePoint includes the ability to Provide views of data that can be easily manipulated by the users, including joining data to create complex data displays Provide limited update capability for users to post data updates to backend systems Create secured profiles of data (down to the field level) that can be used across the farm
Provide a Profile Page that is used to view external data, based on the BDC definition Provide the ability to pull BDC data directly into SharePoint, both as columns and as content types Provide the ability to link BDC data directly to User Profiles Search data sources defined in the BDC, complete with last modified dates While it may seem complicated at first, the BDC is quite a simple concept; the goal is to provide users a way to get, relate, and view data and to keep the programmers out of it. For end users, it provides a way (using several BDC web parts) for users to choose from the data available, mix and match it, join/link it up in various ways, and then display it without any need for coding or development. For developers, the BDC provides a sophisticated way of marrying external data with SharePoint and the use of defined Content Types that can be used anywhere in lists, libraries, web parts, and User Profiles. From a usability point of view, the BDC puts enterprise data into the hands of the users who actually need it without much fuss about where it comes from. The knowledge of the data and internal relationships and the underlying connection and technical field definitions are of no consequence to the user or developer. The only thing that matters is what entities the data source represents. In real terms, the BDC enables working with enterprise data the same way SharePoint lists work. This is pretty cool when you think about the power available; users (and developers) can associate things themselves by what the item is without caring whats behind it. This puts data viewing more in line with the way typical users actually work. With the BDC, users can pick and choose entities as black boxes, which means that users can organize and relate things that are naturally associated (in their minds). They can even create complex joins between entities that arent actually related; for example, using data from Siebel and PeopleSoft to determine personnel cost by customer. To start off with covering the mechanics, there are a few components that make up the BDC: Data definitions These are created by developers who define the how and what of a data source (database or web service) and include the connection information and data format returned. Content Types These are used by users defined by the Data Definitions and are managed by Site Administrators (enabled or disabled as desired). BDC web parts These are used by end-users for displaying, searching, and manipulating data. The best place to start is the heart of the BDC, which is the data definitions that define data sources, whether theyre databases or web services. First, the data source is described (using XML) in SharePoint, which includes the connection information and the format of the data returned (including the database column types used to map them to SharePoint Content Types). This encapsulates the nitty-gritty of the connection itself (including security), which removes the usual barriers of accessing a data source. In the BDC, all of the information, connection, and login details are completely abstracted away from users, designers, and developers.
Web Chapter 1:
The fact that the BDC is called a Catalog is by design. It is a Data Source Catalog and can even be complemented with associations in order to accessorize the data to get the view wanted. Just imagine if all of the data sources in your enterprise, such the Siebel CRM customer records, the help desk call center statistics, the issues logs, and the PeopleSoft employee records were spread all over the place. To find any common information between them, youd have to go to each system manually taking notes along the way. Sound familiar? Now imagine you have a catalog of business data you can browse through and select just what you want. As the user, you dont care how that data is returned or how to connect to it since this is defined in the BDC Data Source Definition. You can accessorize it with data associations (relationships) to other data. Without programming, data (related or not) can be linked to make a view of some entity or thing; for example, linking a Siebel Customer with Remedy (a trouble ticketing system). This data can even be brought into SharePoint. The BDC itself is really a manager of definitions of data sources from databases or Web Services. BDC Data Definitions are XML files that define what a data source is and what can be done with it. Once defined, these definitions can be used directly by the BDC web parts, the matching Content Types used in lists and libraries, and in applications you build on top of SharePoint. Because the BDC is a Shared Service, the data it represents can be used across any sites associated to the Shared Service Provider (SSP); this means either site-specific or farm-wide. Data definitions can also be localized; data column names have display names that can be used to display data in another language with headings to match. To handle data display, the BDC web parts allow you to create queries, provide selections, create custom displays using XSL, and make connections between parts (master/child and filtering), all without writing a line of code. (Note that Xsl is code, but it can be created using SharePoint Designer.) As a Content Type, the BDC gives you a way to pull data from backend systems directly into SharePoint. I say pull because the BDC can be used to actually populate SharePoint lists. BDC Content Types can be used like any other Content Type, and it can also be used to map to Content Types in User Profiles so the right system of record can be used. The BDC is really the fulcrum between data and SharePoint, and it doesnt do much more than that. The BDC holds the definitions (exposing them to SharePoint) and facilitates the pass-through of data by making Methods available. SharePoint handles the display of it (using BDC web parts) or pulls and stores it in lists or User Profiles (when data is pulled and stored in SharePoint, the backend data must be periodically refreshed to keep current, which is covered next). The BDC also enables enterprise search. Data definitions point directly to the data source, whether its a database or web services, and SharePoint can be enabled to index the data and make it searchable. Since the definition is contained in SharePoint, theres nothing that has to be done with the backend; the search engine takes care of all the details. As for viewing data found in external sources, the Profile Page (explained later) is provided so that users can view data much like they view an item in a SharePoint list.
it will return as well as any methods that provide update capability. From a data perspective, the Methods provided by BDC Entities, combined with the metadata, are exactly the same as if you were using a Stored Procedure without all the fuss of dealing with it in .NET code. Because the Method metadata is XML, you can query it to describe the format and field definitions it will return (something you cant do with a Stored Procedure). To understand this concept, lets compare this against creating an application. For example, lets say you wanted to display some data in SharePoint, and you decided to use the traditional ASP.NET method of creating a Stored Procedure using a passed parameter with methods to Add, Update, or Delete a record. In the SQL code, you would then create a procedure that defines the parameter, and then create an If structure to choose the proper SQL command to execute. Users could then use a data view or a developer could create a web part to execute the procedure. In either case, it is up to you to format the data display, and you must know exactly what is being returned. If a change is made, like adding a column, everything has to be changed. You also have a security issue, because users typically dont have access to the database. Using Methods with the metadata (the actual Content Type Definition) you can provide the exact same feature, but with a whole lot less pain. The data definition already has the connection information (and can even support SSO for individual user customization), and each method has its own definition for both the parameters it supports and the fields that will be returned. For a Data View, this is a simple request, and the output can be manipulated using an Xsl style sheet. Programmatically, you can determine the fields at runtime, by simply accessing the BDC metadata XML to enumerate the fields and definitions that are returned by a given method. There is no limit to methods; they can be created to perform whatever command is supported by the web service or database, whether its a service method, a database SQL call, or a Stored Procedure (using Stored Procedures is a best practice).
C AUTION SharePoint does not provide any throttling or limitation on BDC data returned; if a
method returns 5000 records, it will be brought in and eventually be loaded into memory (you can set a max on web parts). It is up to you to define the methods so that such issues are dealt with in the web service or database call.
Web Chapter 1:
Another way of looking at the BDC is to realize that it doesnt really deal with data itself. Instead, it puts a face on it (like a SharePoint List) and makes it available to integrate into SharePoint, both for direct data display and for use as Content Types in lists and libraries. At the same time, it exposes it for you to use in Features, web parts, and other applications:
Data Profiles
The core of the BDC is the data definitions or Data Profiles; a good analogy is to think of Data Profiles as Features for data. These definitions are called a Line of Business Application or LobSystem in BDC terms, and they provide the following: Type of data source (database or web service) How to connect to it (including passing authentication) The operations (methods or actions) it supports What it will return for data (including the format of that data) The idea behind a Line of Business Application (LobSystem) is that an external data source most likely represents a Line of Business System in your enterprise, for example, in your CRM system or your HR system. Of course, the LobSystem name is just a name; the LobSystem can be anything from the current currency conversion rate provided by a web service to a lookup of available meeting rooms. The data definition XML files come in the form of a single file, or they can be broken up into a Model and one or more Resource files:
Web Chapter 1:
The Model file defines the LOB itself, including the name of the LOB and any attributes (like Access Control List information) that go with it. The Properties Resource file defines an LOB Instance and includes the LOB connection and Entities (items). Entities also include the Methods (actions) that can be performed on that data. The Permissions Resource file sets the Access Control List (ACL) rights and permissions on the connection, entities, and methods. The Localized Display Names Resource file defines localized names for entities (like Content Types themselves), which provides ways to label data by use, language, and so on. This file or file(s) are created once and then loaded into the BDC where they are available across all sites associated with a particular Shared Service Provider (SSP). As I mentioned, the Model and Resources can all be defined in the same file; the reason for using separate files is to manage settings without affecting the LOB Instance. Additional Resource files can be loaded as needed to add new localized names and/or modify existing settings without having to reload the LOB from scratch. These files (specifically the Model file) make up the metadata that describes the data source in detail, and it has a dual purpose; it not only describes the data, but also is used by the UI to create the Content Types: System This represents a data source, either a database or a web service, and defines Name This defines the name of the Line of Business System. This is the friendly name that appears in the User Interface (typically something like Customers, Accounts, and so on). Type This defines this data source type, either database or web service. Version This is a fully qualified version number (i.e., 1.0.0.0). Entities These are the things the data source represents, such as Accounts. Methods These are operations that can be performed on an Entity. Method Instances include: Finder These are specific operations within a Method, and they
SpecificFinder This returns a specific item (i.e., SELECT * WHERE). IDEnumerator This returns a list of item keys (like finder but with only one element). Actions These are specific operations that the user can perform; a default is View Profile, which allows viewing a specific item; other actions can be easily created using InfoPath and allow updating data back to the backend system. Associations These describe relationships between Entities (i.e., Customer to Account).
Profile Pages
Profile Pages provide a display of a single BDC data source item and are made available automatically when a definition is loaded. These provide an item-like view similar to a SharePoint list item; it is also used to view individual items returned by Search. The default Profile Page provides a very basic line-item view of the data using two of the BDC Web Parts: the Business Data Item Builder and the Business Data Item Web Parts. Profile Pages are expected to be customized (adding more parts, styles, and so on) as you can certainly see that the default view is pretty bland.
Business Data Item Builder This creates a business data item from parameters in the query string and then communicates them to other parts (this is a default part on the Business Data Profile pages). Business Data List This displays a list of items from a BDC Data Source. Business Data Related List This displays a list of items related to one or more parent items from a BDC Data Source.
Web Chapter 1:
4. Analyst can build Solutions using the BDC Features created. This is done by end users. From a best practice point of view, it would be great if you could follow this flow. However, knowing real life, youll probably find that defining the data, as well as creating and loading the definition is usually done by the developer assigned to the task. End users will only deal with the BDC Web Parts and Content Types. Regardless of who chooses the data, the actual work in the BDC begins with the data definition of some data source. This is either a database or a web service you create, is already part of a Line of Business System, is a subscribed service, and so on. From there, the flow to create the definition is as follows: 1. Define how to connect to the data source (connection string or authentication method). 2. Map the fields and data types that will be returned by the data source. 3. Build the definition file(s). 4. Load the definition file(s) into the BDC. 5. Update the Profile Page for the data source (optional). The previous steps are pretty much done only once and while there is no automated tool for the process (as you will learn later in the chapter) there are ways to accomplish much of it programmatically, using the SharePoint Object Model. From the users perspective, the BDC is based on what has been loaded. When the previous steps have been completed for a specific data source, it immediately becomes available for users to use with BDC Web Parts for viewing data and integrating the BDC Content Type in lists and libraries.
10
To set up a working scenario, assume that these tables represent some data in a company that sells products to restaurant chains. The business basis for the tables is as follows: Each restaurant chain they supply to has a unique Customer Account ID for the company. Each location has its own unique Account IDs. Orders are processed based on the Account ID for the particular location. Each Account has a single account representative assigned to them.
Sample data:
AccountID 1 2 3 4 5 6 7 CustomerAccountID 1 1 1 1 2 2 2 AccountName Jesses #1 Jesses #2 Jesses #3 Jesses #4 Ham N Egger #1 Ham N Egger #2 Ham N Egger #3 AccountCity Charlotte Mooresville Concord Matthews Wilmington New Hope South Port
Web Chapter 1:
11
Sample data:
AcctRepID 1 2 3 AccountID 1 2 5 AcctRepFName Bob Mary Rick AcctRepLName Smith Perkins Allen AcctRepEmail bobsmith@moss.com maryperkins@moss.com richallen@moss.com
Sample data:
OrderID 1001 1002 1003 AccountID 1 1 2 LineItems 2 5 1 OrderName Restock Order Seasonal Promo HRApplications OrderDate 3/15/2007 12:00:00 AM 4/1/2007 12:00:00 AM 4/10/2007 12:00:00 AM
To follow this example, you must have at least one Customer Account with two Accounts defined (rows), one Order tied to an AccountID, and at least one account representative tied to the CustomerAccountID. You can create as much data as you want here if you decide not to use these tables, but be aware that I will be referring to this structure in the following examples.
12
There are some third-party tools now available that do get most of the job done, and they save a lot of typing. One of these tools is the CodePlex DB Metadata Generator available for download at http://www.codeplex.com/DBMetadataGenerator/Wiki/View.aspx. This tool works quite well, and the source code is available, which will provide much better insight to the Administration Object Model than I could possibly provide here. One note if you use this tool: be aware that tables must have primary indexes for this tool to correctly generate the SpecificFinder Method (explained next). Another tool is available (for development and for purchase) at http://www.bdcmetaman.com/default.aspx. This is a bit more advanced, but at $1200 retail, it seems more targeted at consulting groups and solutions builders and is likely not for the average company (the extra effort to build it manually is minimal). To define the files, lets look at the structure of the LobSystem (data) definition. The Model File defines the data and is the actual metadata reference SharePoint storesall information can be specified in this one file. Resource files are used to merge with the metadata to define localized names, set permissions or properties, or to change something like a connection string. The format for these files is defined by the bdcmetadata.xsd and bdcmetadataresource. xsd files, which are located in <drive>\Program Files\Microsoft Office Servers\12.0\Bin. The outline structure for the file in XML (basically the same as the object model) is as follows:
LobSystem This defines the Line of Business System that the data source represents; there is only one of these per file, though conceptually, Microsoft may enable use of more than one. This defines the Instance for this LOB (only one is permitted). This defines the rights to access this LOB instance. This defines the data elements this source represents. This defines the rights to access the Entity. This defines a local name for the Entity; used as a friendly name or for language localization. This defines the indexer or primary key for the data; this is required to enable search for this data source. This defines a Method (action) that can be performed, such as returning an item, returning all items, return the index (for search) and so on. This defines filters of what data to return. This defines passable parameters. This defines the type of parameter. This defines the parameter default. This defines one of the Method Instance Functions.* This defines Actions (such as reload data). This defines any parameters needed for the Action. This creates a relational association between Entities. This defines the rights to access this Association.
Web Chapter 1:
13
This defines a local name for the Association. This defines the Source Entity Reference. This defines the Destination Entity Reference.
* Method Instance Functions are used to perform certain functions and include FinderInstance (for returning all items), SpecificFinderInstance (for returning a single item), IDEnumerator, and IDEnumeratorInstance, which are defined to enable search.
To make this view a little clearer, I included the Access Control List and Localized Display Names entries so you can see that they can be applied at all levels. These settings can be included in a single file (either a Model or combined file) or separated out as Resource files (typical for localized names). There is little difference in the format file types, but their schemas are different; Model files use bdcmetadata.xsd schema and Resource files use bdcmetadataresource.xsd. In practice, though, the difference is that the Model is used to create a new version of a LobSystem. Resource files are merged in with the existing definition to add, remove, or modify security, properties, and localized names. The main reason for the different files is that you can create one LobSystem definition and use it on multiple SSPs. The security, properties available, and localized names can then be merged separately, providing individual SSPs with custom settings (while not changing the core). Even if multiple SSPs are not used, it is a best practice to keep Model and Resource files separate since they each have different purposes, and it can keep the definitions a lot cleaner and easier to read. As well, resource files can also be used to modify single items in the existing definition (like a connection string) without having to reload everything from scratch.
As you can see, this file references the BDC Namespace and defines the LobSystem and LobSystem Instance. Note that Microsofts design premise here is that for one Line of Business System there can be multiple LOBSystemInstances, with each instance defining a different data source in the LobSystem. However, for at least this release, only one instance is supported.
14
How you begin building this file is up to you. Some people like to use SharePoint Designer and others use XML Editor, but my preference is Visual Studio because referencing the Namespace Automatic Tag Creation is what I will use in this example: 1. Open Visual Studio and create a new Empty Project. 2. When the project opens, the first thing you want to do is add the XSD files to the project, which provides code sense when working with the XML code. Right-click on the project name in the Solution Explorer and then select Add | Existing Item. 3. When the file dialog appears, navigate to where the Microsoft Office Servers bin folder is installed (in this example, its the default location c:\Program Files\ Microsoft Office Servers\12.0\bin). 4. Select the two XSD files (bdcmetadata.xsd and bdcmetadataresource.xsd) and click Add:
5. Next, from the toolbar, select File | New |File (or press CTRL-N), select an XML file in the dialog box, and then click Open to open it in the editor:
Web Chapter 1:
15
6. To get started, you specify the XML namespace and type of LobSystem. The first two lines of the file look like this (notice that the XML line includes standalone=yes):
7. Everything shown is the same regardless of the LOB. The exception here are the three attributes: Name Type This is the name for this LobSystem (as it will appear in the BDC). This is set to either database or web service. Version This is set to the current version of this LobSystem.
16
8. The next section defines the LobSystem Properties. At the top of this section, you will want to set the WildCard Character used for this LOB (similar to SQL, as for a value like %somevalue% ). Add this section as shown:
NOTE The previous step applies to filters that you will add later. I mention it here because this is the
correct placement of the XML (at the top of the definition). If you do not use filters, this code has no effect so there is no harm in adding it. 9. The next section is where you can specify specific access control rights. The code looks like this:
<AccessControlList> <AccessControlEntry Principal="MSPSD\spsservices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList>
10. The previous code grants Edit, Execute, SetPermissions, and SelectableInClients (All Rights) to the account MSPSD\SPSServices. Note that you do not have to add this code. I am showing this for demonstration purposes; the BDC permissions can be set via the SharePoint User Interface so you dont need to add it here. (For reference, ACLs like the previous one allow you to set specific rights on individual items, even Associations). The next section defines the LobSystem Instance. The code for this is as follows:
<LobSystemInstances> <LobSystemInstance Name="LOBCustomerAccountInstace"> <Properties> <!--AuthenticationMode can be set to PassThrough, RevertToSelf, RdbCredentials, or WindowsCredentials. --> <Property Name="AuthenticationMode" Type="System.String">PassThrough</Property> <!-- Can be SqlServer, OleDb, Oracle, or Odbc for database systems. --> <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property> <!-- The name of your server hosting the database or SQL Server Instance --> <Property Name="RdbConnection Data Source" Type="System.String">MOSSSPSDEV</Property> <!-- The name of the database --> <Property Name="RdbConnection Initial Catalog" Type="System.String">Account_DB</Property> <!-- The type of connection (SSPI means Windows Integrated) -->
Web Chapter 1:
17
<Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property> <!-- Enable/Disable Connection pooling --> <Property Name="RdbConnection Pooling" Type="System.String">false</Property> </Properties> </LobSystemInstance> </LobSystemInstances>
As you can see, this denes the type of connection, the database server, the database name, and so on. As I mentioned previously, the idea is that multiple LobSystemInstances can be denedhowever, at this time only one is supported. Note that connections here support multiple types; Pass Through is the default, but it can support Revert To Self and even use SSO. For example, to connect to an Access Database, the connection is a bit different:
<Properties> <Property Name="AuthenticationMode" Type="System.String">RevertToSelf</Property> <Property Name="DatabaseAccessProvider" Type="System.String">Odbc</Property> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbConnection Data Source" Type="System.String"> Data Source=''; Driver={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=\\hostserver\fileshare\ActualDBName.accdb;Trusted_Connection=true;</Property> <Property Name="RdbConnection Integrated Security" Type="System.String">False</Property> </Properties>
If you are using Single Sign-On (for example, using a SQL Login instead of a domain login), you would dene the SSO Application and then set the connection properties similar to this:
<Properties> <Property Name="AuthenticationMode" Type="System.String">RdbCredentials</Property> <Property Name="DatabaseAccessProvider" Type="System.String">SqlServer</Property> <Property Name="RdbConnection Data Source" Type="System.String">Server Name (hosting SQL)</Property> <Property Name="RdbConnection Initial Catalog" Type="System.String">Database Name</Property> <Property Name="RdbConnection Integrated Security" Type="System.String">false</Property> <Property Name="RdbConnection Pooling" Type="System.String">true</Property> <Property Name="SsoApplicationId" Type="System.String">SSO App Name</Property> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="SsoProviderImplementation" Type="System.String">Microsoft.SharePoint.Portal.SingleSignon.SpsSsoProvider, Microsoft.SharePoint.Portal.SingleSignon, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Property> </Properties>
18
11. Next, you need to define Entities; that is, whats in this service or database. Then you define Methods for those Entities. This is not really complicated; it just says that for a Method, such as FindAccounts, shown later, that the fields returned will be as defined. The Entity entry defines the name of the Entity. In this example, that happens to be CustomerAccount (Customer Account = a real Entity in the business). This also includes an optional attribute called EstimatedInstanceCount (this is not in the Xsd), which specifies the maximum number of items this particular data source can return. Below that youll see the Identifier defined as the AccountID. As you might guess, this represents a primary key for the data source (note that this should actually be the primary key if this is a database):
<Entities> <Entity Name="CustomerAccount" EstimatedInstanceCount="10000"> <Identifiers> <Identifier Name="AccountID" Name="System.Int32" /> </Identifiers>
12. An Entity cant do anything by itself; it must have Methods defined to act on it. The first Method is called the Finder Method, which is used to return all items in the Entity. This defines the command type and the actual command to return the data; for a database, this is as shown in the two properties (while Im indicating a single SQL Select statement here, this can be any kind of call, Stored Procedure, or similar):
<Methods> <!-- Sets the Method Name --> <Method Name="FindCustomerAccounts"> <Properties> <!-- Specifies the type of command being passed --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property> <!-- The actual command to run --> <Property Name="RdbCommandText" Type="System.String">SELECT * FROM CustomerAccounts</Property> </Properties>
13. Now that the Method is defined, the BDC needs to know exactly what is returned by this Method. These are the actual fields (columns) that the data source returns; they are listed as Parameters and are mapped to the same definitions as in the database:
<Parameters> <!-- Sets which way the data is going --> <Parameter Direction="Return" Name="CustomerAccounts"> <!-- Specifies the DB Reader and that it is a collection --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="CustomerAccountDataReader"> <TypeDescriptors> <!-- Specifies the Record Name --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor Name="CustomerAccountDataRecord" TypeName="System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
Web Chapter 1:
19
<!-- Specifies the Fields (Columns) in the record returned --> <TypeDescriptors> <!-- Specifies that this field is the Identifier --> <TypeDescriptor Name="AccountID" TypeName="System.Int32" IdentifierName="AccountID" /> <TypeDescriptor Name="CustomerAccountID" TypeName="System.Int32" /> <TypeDescriptor Name="AccountName" TypeName="System.String" /> <TypeDescriptor Name="AccountCity" TypeName="System.String" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters>
14. Next, the MethodInstances (actual actions) of this Method must be defined; as the Finder Method Instance, this action is intended to return all items (up the max count if one was specified) as a list:
<MethodInstances> <!-- Notice Type = Finder and Return Param is CustomerAccounts --> <MethodInstance Name="FindCustomerAccountsInstance" Type="Finder" ReturnParameterName="CustomerAccounts" ReturnTypeDescriptorName="CustomerAccountDataReader" ReturnTypeDescriptorLevel="0"> </MethodInstance> </MethodInstances> </Method>
15. The next Method that is defined is the SpecificFinder Method. The intent of this one is to return a single row or item based on something passed to it (note that this Method must be defined for Profile Pages in the BDC to work). This is pretty much the same as the Finder Method, except a Parameter is added and the SQL Statement updated with a Where clause:
<!-- Sets the Method Name --> <Method Name="FindCustomerAccount"> <Properties> <!-- Specifies the type of command being passed --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property> <!-- The actual command to run --> <Property Name="RdbCommandText" Type="System.String">SELECT * FROM CustomerAccounts WHERE AccountID = @AccountID</Property> </Properties> <Parameters> <!-- Sets the Inbound Parameter --> <Parameter Direction="In" Name="@AccountID" > <!-- Sets the Inbound Parameter to the Identifier Type --> <TypeDescriptor Name="AccountID" TypeName="System.Int32" IdentifierName="AccountID" /> </Parameter> <!-- Sets the Return Parameter --> <Parameter Direction="Return" Name="CustomerAccounts" >
20
<!-- Specifies the DB Reader and that it is a collection --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e 089" IsCollection="true" Name="CustomerAccountDataReader"> <TypeDescriptors> <!-- Specifies the Record Name --> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor Name="CustomerAccountDataRecord" TypeName="System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <!-- Specifies the Fields (Columns) in the record returned --> <TypeDescriptors> <!-- Specifies that this field is the Identifier --> <TypeDescriptor Name="AccountID" TypeName="System.Int32" IdentifierName="AccountID" /> <TypeDescriptor Name="CustomerAccountID" TypeName="System.Int32" /> <TypeDescriptor Name="AccountName" TypeName="System.String" /> <TypeDescriptor Name="AccountCity" TypeName="System.String" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters>
16. Last, the MethodInstances (actual actions) for the Specific Finder Method must be specified:
<MethodInstances> <!-- Notice Type = SpecificFinder and Return Param is CustomerAccounts --> <MethodInstance Type="SpecificFinder" ReturnParameterName="CustomerAccount" ReturnTypeDescriptorName="CustomerAccountDataReader" ReturnTypeDescriptorLevel="0" Name="FindCustomerAccountInstance"> </MethodInstance> </MethodInstances> </Method> </Methods>
18. Save this file as LOBCustomerAccounts_model.XML. At this point, you are ready to load the file into the BDC; if there are any problems with the file definition, this is where you will find out.
Web Chapter 1:
21
While you only need to set up the methods for the ones you want, I suggest a best practice for setting up all of them, including Finder, SpecificFinder, and IDEnumerator (shown later in the chapter). You might not need it today, but there is no sense in restricting yourself (and having to add XML) later. Also as a technical note, if the underlying data schema changes, you may need to modify the data definition metadata to reflect the change, and it might also break web parts that are dependent on the data returned. Adding a column is usually not an issue, but a rename or drop of a column means a do-over.
22
4. Notice that you have the option of loading a Model or a Resource file. If you load a Model file, it assumes a re-create of the definition from scratch (overlay if you will) as a new version. Resource files are uploaded to make changes to permissions, localization, and so on. Also notice that if this file does include resource definitions that you can choose which ones you want to load. Click on the Import button to start the import. During the Import, the BDC loader will parse the XML file and try to load the definition. If theres any problem, it will tell you exactly what line the problem occurred on. Two common issues are not defining a SpecificFinder method that will warn that a profile page for the data source was not created (it has no key to use) and errors in the XML syntax (bad spelling, incorrect name, and so on). Assuming the import is successful, click the OK button to complete the load. This brings you to the BDC Definition Page, which shows what Entities are loaded for this LobSystem:
Web Chapter 1:
23
5. To view what the Entity looks like in the BDC, click on the name to open the view:
24
6. As you can see, this tells you pretty much everything about this particular data source, including whether it is crawlable by Search, the Parameters (fields/ columns) that are included in it, any Associations and Actions, and so on. Notice that there is a link under the Actions sectionView Profile. Click this to open the particular Action settings (this is the same as if you had added one manually):
7. The URL specified here points to the actual page that is opened when this action is used (you can also specify that it open in a new page). You can add items here directly to further qualify the action with additional parameters. For example, adding a new Parameter allows selecting additional Parameter fields: 8. You dont want to make any changes here, but you should copy the URL shown to view the profile (below). Click the Cancel button to return. Notice that on this page (as well as most others in the BDC), you can also manage permissions. If you click the Manage Permissions link, this is displayed:
Web Chapter 1:
25
26
<Identifiers> <Identifier Name="AccountID" /> </Identifiers> <Methods> <Method Name="FindCustomerAccounts"> <AccessControlList> <AccessControlEntry Principal="MSPSD\SPSServices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> <Parameters> <Parameter Name="CustomerAccounts"> <TypeDescriptor Name="CustomerAccountDataReader"> <TypeDescriptors> <TypeDescriptor Name="CustomerAccountDataRecord"> <TypeDescriptors> <TypeDescriptor Name="AccountID" /> <TypeDescriptor Name="CustomerAccountID" /> <TypeDescriptor Name="AccountName" /> <TypeDescriptor Name="AccountCity" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountsInstance"> <AccessControlList> <AccessControlEntry Principal="MSPSD\SPSServices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> </MethodInstance> </MethodInstances> </Method> <Method Name="FindCustomerAccount"> <AccessControlList> <AccessControlEntry Principal="MSPSD\SPSServices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> <Parameters> <Parameter Name="@AccountID"> <TypeDescriptor Name="@AccountID" />
Web Chapter 1:
27
</Parameter> <Parameter Name="CustomerAccount"> <TypeDescriptor Name="CustomerAccountDataReader"> <TypeDescriptors> <TypeDescriptor Name="CustomerAccountDataRecord"> <TypeDescriptors> <TypeDescriptor Name="AccountID" /> <TypeDescriptor Name="CustomerAccountID" /> <TypeDescriptor Name="AccountName" /> <TypeDescriptor Name="AccountCity" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountInstance"> <AccessControlList> <AccessControlEntry Principal="MSPSD\SPSServices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> </MethodInstance> </MethodInstances> </Method> </Methods> <Actions> <Action Name="View Profile"> <ActionParameters> <ActionParameter Name="AccountID" /> </ActionParameters> </Action> </Actions> </Entity> </Entities> </LobSystem>
28
Web Chapter 1:
29
LCID="2072">Cont Nume</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor Name="AccountCity"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Account City</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Cont Oras</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountsInstance" /> </MethodInstances> </Method> <Method Name="FindCustomerAccount"> <Parameters> <Parameter Name="@AccountID"> <TypeDescriptor Name="@AccountID" /> </Parameter> <Parameter Name="CustomerAccount"> <TypeDescriptor Name="CustomerAccountDataReader"> <TypeDescriptors> <TypeDescriptor Name="CustomerAccountDataRecord"> <TypeDescriptors> <TypeDescriptor Name="AccountID"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">ID</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">ID</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor Name="CustomerAccountID"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Customer Account ID</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Client Cont ID</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor Name="AccountName"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Name</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Nume</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor Name="AccountCity"> <LocalizedDisplayNames> <LocalizedDisplayName
30
LCID="1033">Account City</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Cont Oras</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountInstance" /> </MethodInstances> </Method> </Methods> <Actions> <Action Name="View Profile"> <ActionParameters> <ActionParameter Name="AccountID" /> </ActionParameters> </Action> </Actions> </Entity> </Entities> </LobSystem>
Notice the LocalizedName definition for the Entity is simply an element; in the TypeDescriptors, it must be within the tag. Also, for a list of Language Code Identifiers (LCIDs), you can simply search the Web or the Microsoft site.
Web Chapter 1:
31
Type="System.String">MOSSSPSDEV</Property> <Property Name="RdbConnection Initial Catalog" Type="System.String">Accounts_DB</Property> <Property Name="RdbConnection Integrated Security" Type="System.String">SSPI</Property> </Properties> </LobSystemInstance> </LobSystemInstances> <Entities> <Entity Name="CustomerAccount"> <Properties> <Property Name="DefaultAction" Type="System.String">View Profile</Property> </Properties> <Identifiers> <Identifier Name="AccountID" /> </Identifiers> <Methods> <Method Name="FindCustomerAccounts"> <Properties> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property> <Property Name="RdbCommandText" Type="System.String">SELECT * FROM CustomerAccounts</Property> </Properties> <Parameters> <Parameter Name="CustomerAccounts"> <TypeDescriptor Name="CustomerAccountDataReader"> <TypeDescriptors> <TypeDescriptor Name="CustomerAccountDataRecord"> <TypeDescriptors> <TypeDescriptor Name="AccountID" /> <TypeDescriptor Name="CustomerAccountID" /> <TypeDescriptor Name="AccountName" /> <TypeDescriptor Name="AccountCity" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountsInstance" /> </MethodInstances> </Method> <Method Name="FindCustomerAccount"> <Properties> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandText"
32
Type="System.String">SELECT * FROM CustomerAccounts WHERE AccountID = @AccountID</Property> </Properties> <Parameters> <Parameter Name="@AccountID"> <TypeDescriptor Name="@AccountID" /> </Parameter> <Parameter Name="CustomerAccount"> <TypeDescriptor Name="CustomerAccountDataReader"> <TypeDescriptors> <TypeDescriptor Name="CustomerAccountDataRecord"> <TypeDescriptors> <TypeDescriptor Name="AccountID" /> <TypeDescriptor Name="CustomerAccountID" /> <TypeDescriptor Name="AccountName" /> <TypeDescriptor Name="AccountCity" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindCustomerAccountInstance" /> </MethodInstances> </Method> </Methods> <Actions> <Action Name="View Profile"> <ActionParameters> <ActionParameter Name="AccountID" /> </ActionParameters> </Action> </Actions> </Entity> </Entities> </LobSystem>
Web Chapter 1:
33
<Method Name="GetAllAccountIDs"> <Parameters> <Parameter Name="AccountIDs" Direction="Return"> <!-- This returns an Array of Ints --> <TypeDescriptor Name="AccountID" TypeName="System.Int32[]" IsCollection="true"> <TypeDescriptors> <TypeDescriptor Name="AccountID" IdentifierName="AccountID" ReturnParameterName="AccountIDs" TypeName="System.Int32" /> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="GetAccountIDsInstance" Type="IdEnumerator" /> </MethodInstances> </Method>
Filters
Filters are defined as a part of methods. They are used to control ways to handle the data that Finders return as well as extend the Methods capabilities by providing user-settable parameters that are used to filter data returned. Filters themselves are footnotes or addendums to Method input parameters (a tag if you will) that can be set by users or preset using System Filters. User-settable parameters can be any item within the data source; system filters provide prefilled parameters such as the current user (and cannot be overridden by the user).
NOTE The Wildcard character defined at the top of the LobSystem shown previously is used by
filters as defined here. There are several kinds of filter types that define how to filter the data, which allows creation of like comparisons and use of wildcards as follows: Wildcard This provides a like condition as in WHERE FName LIKE %Bob%; this provides conditions of Starts With and Contains. Comparison This provides a WHERE comparison, such as WHERE Region=Eastern. Limit This sets a limit on how many items are returned by the service or database; this basically is a way to prevent users from pulling too much data at one time. UserContext This limits the data returned by filtering it down to what the current user actually has access privilege to (similar to how the Search service works). Username Passes the SSO username as part of the filtering (used for passing username to the backend data source). Password This is the same as Username, but for the SSO Password. UserProfile This creates a filter based on User Profile properties that can be selected. SSOTicket This passes the SSO ticket as a parameter (used for SSO handling and useful when multiple LobSystems use the same authentication). LastIdSeen This passes the last IDEnumerator (covered later) seen by the user, allowing the data source to return data from a starting point (think paging of data).
34
Each of these can include a few optional properties: UsedForDisambiguation If true, this particular filter is used to generate a list of possible matches (kind of like IDEnumerator). CaseSensitive If true, the filter is case sensitive (typical for passwords). IsDefault If true indicates that this is the default filter. The purpose of using filters is to provide a dynamic way of selecting data based on different criteriaeven without having to create a new MethodInstance for each. Filters are part of the Method definition and are added just after the <Method> tag and before the <Parameters> tag (outside of the ACL entry if there is one). The Parameter needed for the filter (what is passed when the filter is used) is added within the <Parameters> tag. As shown next, this defines a new Wildcard Filter for City and defines a new (inbound) parameter for it:
... </Properties> <FilterDescriptors > <FilterDescriptor Name="City" Type="Wildcard" /> </FilterDescriptors> <Parameters> <Parameter Name="@City" Direction="In"> <TypeDescriptor Name="City" AssociatedFilter="City" TypeName="System.String" /> </Parameter> ...
Associations
Associations create relationships between Entities similar to a Join in SQL. An Association has one or more Source Entities and one Destination Entity tied together by a common key (in this example, AccountID from the CustomerAccounts table). There are two parts to an Association: first, another Entity must be defined, for the LobSystem will represent the associated Entity (in other words, what its being linked with), and second is the definition of the Association between the Entities. In this example, individual accounts each have an associated Account Representative; the join or common key is the Account ID that appears in both tables. The first step is to define a new Entity in the LobSystem for representing the Account Representative data and to set up an Identifier (a key) for the Account ID (note that the actual key for this table is the AcctRepID, and that this definition overrides that):
<!-- Start of AccountRep Entity --> <Entity Name="AccountRep" EstimatedInstanceCount="10000"> <Identifiers> <Identifier Name="AccountID" TypeName="System.Int32" /> </Identifiers> <Methods> <Method Name="FindAccountRepForAccount"> <Properties> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandType" Type="System.Data.CommandType, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">Text</Property>
Web Chapter 1:
35
<!-- NOTE: KEEP THIS ON ONE LINE! --> <Property Name="RdbCommandText" Type="System.String">SELECT [AcctRepID], [AccountID], [CustomerAccountID],[AcctRepFName], [AcctRepLName], [AcctRepEmail] FROM [AccountReps] WHERE [AccountID] = @AccountID</Property> </Properties> <Parameters> <Parameter Name="@AccountID" Direction="In" > <TypeDescriptor Name="@AccountID" IdentifierName="AccountID" IdentifierEntityName="CustomerAccount" TypeName="System.Int32" /> </Parameter> <Parameter Name="AccountRepForAccount" Direction="Return" <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor Name="AccountRepForAccountDataReader" TypeName="System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true"> <TypeDescriptors> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor Name="AccountRepForCustomerDataRecord" TypeName="System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <TypeDescriptors> <TypeDescriptor Name="AcctRepID" TypeName="System.Int32" /> <TypeDescriptor Name="AccountID" IdentifierName="AccountID" TypeName="System.Int32" /> <TypeDescriptor Name="CustomerAccountID" TypeName="System.Int32" /> <TypeDescriptor Name="AcctRepFName" TypeName="System.String" /> <TypeDescriptor Name="AcctRepLName" TypeName="System.String" /> <TypeDescriptor Name="AcctRepEmail" TypeName="System.String" /> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Name="FindAccountRepForAccountInstance" Type="SpecificFinder" ReturnParameterName="AccountRepForAccount" ReturnTypeDescriptorName="AccountRepForAccountDataReader" ReturnTypeDescriptorLevel="0" /> </MethodInstances> </Method> </Methods> </Entity> <!-- End of AccountRep Entity -->
NOTE If using Localization, Local Names must be defined for this Entity.
Notice that Im also following a best practice here, and Im not using SELECT * and opting to select each individual column. This guarantees that as long as fields are not deleted or types changed, the definition will continue to work and that columns can be added and so on, without causing any problems here (not true using SELECT *). Once the Entity has been defined, an Association must be created; this is done at the same level as
36
Entities (which is logical since it joins entities in some manner) within the LobSystem definition. In this example, Im joining the Customer Account Entities individual Account ID to the Account Representative Entity Account ID:
<!-- Start Associations (these are same level as Entities): --> <Associations> <Association Name="AccountToAcctRep" AssociationMethodEntityName="AccountRep" AssociationMethodName="FindAccountRepForAccount" AssociationMethodReturnParameterName="AccountRepForAccount" IsCached="true"> <!-- The Source of the Key Value --> <SourceEntity Name="CustomerAccount" /> <!-- The Receiver of the Key Value --> <DestinationEntity Name="AccountRep" /> </Association> </Associations> <!-- End of Associations -->
Web Chapter 1:
37
Type="System.String">SELECT [OrderID],[AccountID],[LineItems],[OrderName],[OrderDate] FROM [OrderMaster] WHERE [AccountID] = @AccountID</Property> </Properties> <AccessControlList> <AccessControlEntry Principal="MSPSD\spsservices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> <Parameters> <Parameter Direction="In" Name="@AccountID"> <TypeDescriptor TypeName="System.Int32" IdentifierEntityName="CustomerAccount" IdentifierName="AccountID" Name="@AccountID" /> </Parameter> <Parameter Direction="Return" Name="OrdersForAccount"> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor TypeName="System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" IsCollection="true" Name="OrdersForAccountDataReader"> <TypeDescriptors> <!-- NOTE: KEEP THIS ON ONE LINE! --> <TypeDescriptor TypeName="System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Name="OrdersForCustomerDataRecord"> <TypeDescriptors> <TypeDescriptor TypeName="System.Int32" Name="OrderID"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">ID</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">ID</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor TypeName="System.Int32" IdentifierName="AccountID" Name="AccountID"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Account ID</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Cont ID</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor TypeName="System.String" Name="LineItems"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Item Count</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Numarul articole</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor TypeName="System.String" Name="OrderName"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Order Name</LocalizedDisplayName> <LocalizedDisplayName
38
LCID="2072">Comand<<Unicode: 61>\> Nume</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> <TypeDescriptor TypeName="System.String" Name="OrderDate"> <LocalizedDisplayNames> <LocalizedDisplayName LCID="1033">Order Date</LocalizedDisplayName> <LocalizedDisplayName LCID="2072">Comand<<Unicode: 61>\> Data</LocalizedDisplayName> </LocalizedDisplayNames> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </TypeDescriptors> </TypeDescriptor> </Parameter> </Parameters> <MethodInstances> <MethodInstance Type="Finder" ReturnParameterName="OrdersForAccount" ReturnTypeDescriptorName="OrdersForAccountDataReader" ReturnTypeDescriptorLevel="0" Name="FindOrdersForAccountInstance"> <AccessControlList> <AccessControlEntry Principal="MSPSD\spsservices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry> </AccessControlList> </MethodInstance> </MethodInstances> </Method> </Methods> </Entity>
As you can see, this is the full definition, including permissions and so on. You can also see that the Localization has been setin this case, English and Romanian. Methods defined for this entity indicate what can be done with it. In this example, a method to return Orders related to an Account (again using best practices by specifying exactly which fields are to be returned instead of using SELECT *). Once the Entity itself has been added, the Association must be added as well:
<Association Name="AccountToOrders" AssociationMethodEntityName="OrdersByAccount" AssociationMethodName="FindOrdersForAccount" AssociationMethodReturnParameterName="OrdersForAccount" AssociationMethodReturnTypeDescriptorName="OrdersForAccountDataReader" AssociationMethodReturnTypeDescriptorLevel="0" IsCached="true"> <AccessControlList> <AccessControlEntry Principal="MSPSD\spsservices"> <Right BdcRight="Edit" /> <Right BdcRight="Execute" /> <Right BdcRight="SetPermissions" /> <Right BdcRight="SelectableInClients" /> </AccessControlEntry>
Web Chapter 1:
39
You can add as many associations as needed, simply by defining an Entity and an Association as shown previously; using this, you can completely emulate the relational structure of any data source. Also remember that the granular level of security can limit access to associations above and beyond the data source and SharePoint. For example, you may have an Employee Information Entity; Association to something like Salary can be restricted simply by setting the right on the Association itself.
40
As you can see, there are two web parts here: the first is the Business Data Item Builder Web Part. This particular part reads data from the URL and can pass it on to any other web part via connections. The other part is the Business Data Item Web Part, which displays a simple list of a data record (based on the one passed to it by the Business Data Item Builder Part). You can see the connection here:
Be aware that this data is live and is refreshed directly from the data source each time the page is shownnothing is actually stored in SharePoint for this. This Profile Page can be considered the Home Page (and Search View Page) for the data and can obviously be linked to either, through regular links or as done programmatically. Although viewing a single record is useful, this page can also be enhanced using other web parts to show some additional information. For example, you have an Association (relationship) defined for this LobSystem between the Customer Account (as shown) and the Account Representatives. To show this relationship (after all, its always handy to know the Account Representative when looking at the account), do the following: 1. From the Profile Page, click Add a Web Part in any zone. 2. When the Add Web Part dialog appears, find the Business Data Related List Web Part, click the check box, and then the Add button to add it to the page. This will show that it is not yet configured. 3. Click the Open the Tool Pane link to open the tool pane:
Web Chapter 1:
41
5. Obviously, only one has been defined in this particular SSP. Click to select it and then click OK. On return to the page, the selected item and the Relationship dropdown are filled with all available Associations (in this case only one). 6. Click the Apply and OK buttons to close out the tool pane. The part is displayed with a message that it has no connection (and wants one to supply Customer Account). 7. The connection value this particular relationship needs is the Account ID and both of the preexisting web parts supply this. However, in this case, it is best to use the Customer Account. The connection can be made either way, from the Customer Account display or from the Business Data Related List just created. Using the Edit menu, select Connections | Get Related Item From | Customer Account Details as shown:
42
8. This will tie the Customer Account Details (specifically the Account ID) to the AccountReps List:
9. This now represents two connections: the Business Data Item Web Part that pulls the AccountID from the Query String in the URL and passes it to the Customer Account Details View. This, in turn, passes the AccountID on to the AccountReps list, which filters to show the account representative for the account shown. Note that this display isnt necessarily pretty and may not be exactly what you want. You have two options here: notice the Edit View link, which allows you to manage how the view looks:
10. This allows you to customize the view just like any other SharePoint list. Note, however, that the Xsl can also be modified. Use the Edit menu to select Modify Shared Web Part to open the tool pane, scroll down, and then click on the Xsl Editor:
Web Chapter 1:
43
As you can see, this editor is really a simple text editor and not very conducive to editing. I suggest using Visual Studio or SharePoint Designer, and then cut and paste here. 11. Now, if you havent noticed, you are well on your way to building an actual application. In just a few clicks, this page now represents a view of a customer account and the representative who supports the customerall without having to code anything other than the base definition. Since you added an additional association, you can add that here too. The additional association was Orders By Account, which means you can use this to show current orders for a customer on the profile. To add this, select Site Actions | Edit Page. When the page enters Edit Mode, click Add Web Part in the middle right zone. When the Add Web Part dialog box appears, find Business Data Related List and click the check box to select it:
44
12. Click the Add button to add it to the page. When the part is first displayed, it detects that it is not configured. Click the Open Tool Pane link, and when the tool pane opens on the right, click the Book icon to open the Associations Relationship dialog box. When that opens, click the OrdersByAccount Business Data Type, as shown:
13. Click the OK button to return to the page. When the LobSystem information is read, the Relationship drop-down is automatically set to the first available (in this case, AccountToOrders):
14. Click the OK button to save the settings and return to the page. Next, youll need to create a connection between the Customer Account and the Orders display. Click on the Edit menu in the Customer Account Item, and then select Connections | Send Selected Item To | OrdersByAccount List, as shown:
Web Chapter 1:
45
15. Once the connection is made, you should see any matching orders displayed. Click Exit Edit Mode to see the end result. This one Profile Page is now a view of several customer aspects: the customer, any orders, and their account representative:
As you can see, just by using this simple Profile Page it is now possible to create a complete view of a business entity. Since this is also the page displayed when a BDC item is clicked on when found in Search, this can provide a very powerful tool in the enterprise. For example, if a help desk employee was working with a client, a simple search on the client name returns a link to the Profile Page. Clicking the link, the person now knows all about that client, all on one page. While this is useful, be aware that this example has only scratched the surface of the capabilities available. The real power is that all of the parts shown here (and a few others) can be used to create application-like functionality on pages anywhere in the site.
Actions
In addition to using the BDC to view and search data, it can also be used to perform actions from updating data in a backend system, to showing a data entry form, to e-mailing a message. Actions define the specific options or tasks users can perform using the user interfaceeither with or on the BDC data. Typical actions might be a direct link to view the data item (the Profile Page explained later on in the chapter) or to open up an InfoPath form for users to make updates. This may seem a bit out of order, since Actions are really part of the definition. However, though they are defined there, they are not visible until you can see the Profile Pagethus, the out-of-order sequence with the rest of the options.
46
Actions are part of an Entity just like Methods; you can think of Methods as ways to pull and view data and Actions as what you can do once the data is shown. You might have noticed that you have already defined one:
<Actions> <!-- NOTE: KEEP THIS ON ONE LINE! --> <Action Position="1" IsOpenedInNewWindow="false" URL="http://mossspsdev:100/ssp/admin/Content/ CustomerAccount.aspx?AccountID={0}" ImageURL="/_layouts/1033/images/viewprof.gif" Name="View Profile"> <ActionParameters> <ActionParameter Index="0" Name="AccountID" /> </ActionParameters> </Action> </Actions>
Notice that this action points to the URL of the Profile Page, passing a single parameter of Account ID. Actions are available whenever you are viewing BDC data and are shown in an Item List display or when an item is returned in Search. However, any number of actions can be created, from opening up another form to showing a report. To demonstrate this, navigate to a SharePoint site that is associated with the Shared Services Provider. When the site opens: 1. Click the View All Site Content link. 2. From the All Site Content page, click Create. 3. On the Create Page under the Web Pages Group, click Web Part Page. Name the page BDCActions, choose any layout, and then click OK to create it. 4. When the page appears, click Add a Web Part in any zone. 5. When the Add a Web Part dialog box appears, scroll down to find Business Data List and click the Add button to add it to the page. Click the Open Tool Pane link to configure the list part. 6. Under the Business Data Type, click the book icon to browse for the BDC LobSystem. 7. On the Business Data Type Picker dialog box, click the Customer Account Business Data Type to select it. Then, click the OK button in the tool pane to close it. On return, you should see the List in Query mode, as shown:
Web Chapter 1:
47
8. If you simply click the Retrieve Data link (in either Display or Edit Mode), all data records will be returned. However, as you will notice, this is simply a flat list, and there are no options on any items. To use actions, the view must be modified. With the part in Edit Mode (as shown previously), click the Edit View link. This will open the Edit View Page:
9. Notice that you can set all of the options, including setting the criteria that you want users to be able to select. If you scroll down to the list of displayed columns, you will notice that there is an option called Title next to each. Selecting this means that the Actions menu becomes available under that particular field. For this example, click Title next to Account Name: 10. Scroll to the bottom and click OK to save the change. When you return to the page, click the Retrieve Data link again. This time you will notice that simply moving the mouse over an item (in this case, Account Name) will display the drop-down menu of Actions:
11. As you can see, there is only one Action shown, which is the default View Profile Action.
48
Adding an Action
Actions are based on anything you can do using a URL link, which includes opening an application page, an InfoPath Form, a custom ASPX page, and even sending an e-mail. The benefit is that you can utilize the BDC data as parameters when calling these and pass them as query options in the URL itself. These are called ActionParameters and are pointers to fields in the BDC. Action Options include: Name This is the name shown in the drop-down menu.
DefaultDisplayName This shows as the tooltip. Position This is the position in Business Data Item Display (in the drop-down list). IsOpenedInNewWindow a new browser window. This is set to True or False; when True, the link opens in
IsCached This is set to True or False to indicate whether this option should be cached (should usually be true). ImageURL This specifies the URL for an image to display in the drop-down (note that the relative URL used by default for the View Profile is located in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\template\ LAYOUTS\1033\IMAGES). URL This is the actual URL to execute when the option is clicked. Its basically a redirect, so that any valid URL can be used and any number of parameters can be used to fill in URL options and query values. Action Parameters allow you to reference the BDC data and use it in the action URL: Name Index This is the name shown in the drop-down menu. This is the index of the parameter (i.e. 0 = {0}).
DefaultDisplayName This shows as the tooltip. IsCached This is set to True or False to indicate whether this option should be cached (usually true). As an example, assume you wanted to add two Actions to the Custom Account record: one to notify someone to review the account and another that provides a direct search of the Account Name using MSN.com. In both cases, instead of the Account ID, which is passed in the default View Profile Action, youd need to pass the Account Name instead. Both of these are shown next:
<Action Position="2" Name="Review Account" DefaultDisplayName="Review Account" IsCached="true" IsOpenedInNewWindow="true" URL="mailto:bobsmith@mspsd.com?subject=Account%20Review%20for%20{0}" ImageURL="/_layouts/1033/images/RTEPASTE.GIF" > <ActionParameters> <ActionParameter Index="0" Name="AccountName" DefaultDisplayName="Customer Account Name" IsCached="true" /> </ActionParameters> </Action> <Action Position="3" Name="Search MSN"
Web Chapter 1:
49
DefaultDisplayName="Search for Client on MSN" IsOpenedInNewWindow="true" URL="http://search.msn.com/results.aspx?q={0}" ImageURL="/_layouts/1033/images/PGNXTON.GIF" IsCached="true" > <ActionParameters> <ActionParameter Index="0" Name="AccountName" DefaultDisplayName="Customer Account Name" IsCached="true" /> </ActionParameters> </Action>
To add these actions, you must edit the Application Definition XML file, locate the Entity (in this case Customer Accounts), and then add these actions in between the <Actions> and </Actions> tags. To load the Definition, click View Applications from the Shared Services Provider Administration Page. Mouse over the application name and, from the drop-down menu, select Delete Application. When complete, click Import Application, navigate to find the definition file, and import it. Assuming you have no issues with loading, you can now see the affect of the Actions. If you navigate to the Profile Page for an item, youll see that the new Actions are now available:
These Actions are also available from other displays; if you navigate back to the custom page created previously, you can see that the same options are now available there (this is true when items are displayed in Search as well):
50
To change this to the Search Action from the previous example, edit the Application Definition file, find the Entity, and then the Properties section. Change the name as indicated (this name must match the name used to define the Action):
<Property Name="DefaultAction" Type="System.String">Search MSN</Property>
NOTE While this does set the default, it does not affect the Business Data List Display or the Profile
Display of the item. After making this change to the definition file, it must be uploaded. From the Shared Services Provider Administration Page, click View Applications. Mouse over the application name and from the drop-down, select Delete Application. When its complete, click Import Application, and then navigate to find the definition file and import it.
Web Chapter 1:
51
this was already done twice. First, when setting up the Profile Page with related lists, four different web parts leveraged the Associations to create a complete Customer View. In adding actions, a Custom Web Part Page was created that contained a Business Data List listing the Customer Accounts. The best way to explore each of these parts is simply by example. If you followed the example and already have a Custom Web Part Page created, begin there. If not, you must navigate to a SharePoint site that is associated to the Shared Services Provider where the Application is defined. Select View All Site Content | Create | Web Part Page to create a new page (store it in the local Document Library).
52
3. Click the book icon to browse the Catalog for Entities. Click the name of the Entity to select it (Customer Account is selected here, as shown):
4. Click OK to save the options. Next, click the browse icon for items. This opens up the Query Selection so that you can choose a specific item:
5. Click OK to save the settings. In the background (if you havent guessed), this sets up a query so that each time this is displayed, the correct account is retrieved. Next, you can choose which fields to display by clicking the Fields button:
6. Fields checked will be shown and you can set the order (left to right) in how they will be displayed. Click OK to save any changes. Next, you can set the Actions options by clicking the Actions button. That is, of the Actions defined for the data source, what this particular view is going to support:
Web Chapter 1:
53
Notice that once again, you can set the order here (overriding the default set by the definition); click OK to save any changes. The next setting indicates whether you want new Actions (if made available) to be automatically included here. If this is disabled, adding a new Action must be done manually. Remaining settings have to do with the actual display: Xsl Editor This is a plain text editor that allows modifying the Xsl used to display the data (cut and paste is suggested). Parameters Editor This is a plain text editor that allows the modifying of any parameters defined in XML for this data source (if none, this will be blank). Sample Data This allows entry of a sample data format to be displayed. Xsl Link This allows setting a link to an existing Xsl style sheet. Enable Data View Caching/Caching Time out (Not shown) This sets the cache parameters for this Data Source View. Once you have made your settings, click the Apply button in the tool pane to save them. The selected item should display as shown (click OK in the tool pane to close it):
54
As is true with most, you can also set Display Options here: Xsl Editor This is a plain text editor that allows modifying the Xsl used to display the data (cut and paste is suggested). Parameters Editor This is a plain text editor that allows modifying any parameters defined in XML for this data source (if none, this will be blank).
Web Chapter 1:
55
Sample Data This allows entry of a sample data format to be displayed. Xsl Link This allows setting a link to an existing Xsl style sheet. Enable Data View Caching/Caching Time Out (Not Shown) This sets the cache parameters for this Data Source View. When complete, click OK to close the tool pane. At this point, the two web parts are on the page, one listing a specific account and the other a list of all accounts. However, using Web Part Connections, you can begin to get some actual application functionality out of this. If the page is not in Edit Mode, select Site Actions | Edit Page. Using the Edit Web Part menu on the Business Data Item Web Part, select Modify Web Part Settings. When the tool pane opens, clear the value in the Item, and then click OK to close the tool pane; the web part will indicate that it is not configured. Use the Edit menu again and select Connections | Get Item From | Customer Account List. When the page refreshes, you will now see a change. The Business Data List Web Part now has radio buttons next to each item, and whichever is selected is automatically displayed in the Business Data Item:
56
3. When you click OK and return to the page, you will see that the Relationship dropdown menu is filled (in this example, AccountToAcctRep). Click Apply in the tool pane and the part will indicate that it still needs a connection:
4. Use the Edit menu on the web part to select Connections | Get Related Item From | Customer Account. After the refresh, you should see the connection is made and the account representative is being selected from the Customer Account shown in the Business Data Item Web Part:
Be aware that this connection could have just as easily been made to the Customer Account List since the same key is involved; however, because you know that the Business Data Item (in this case, the Customer Account) will always be the single value needed, it is cleaner in the logic. To finish off the example, repeat adding another Business Data Related List Web Part and this time select Orders. Follow the same steps as shown previously, including setting the connection to the Business Data Item. When complete and the page has been saved, the display should look something like this:
Web Chapter 1:
57
As you can see, both Related Lists use the Since item, so combined, you have a complete data picture, all selectable by a single part (the Business Data List).
58
2. Click OK to save your changes. When you return to the page, using the Edit menu on the web part, select Connections | Get Item From | Customer Account. 3. On refresh, save the page, and you should see the final result looking something like this:
4. To make it come alive, simply enter something in the Business Data List Query Field and click Retrieve Data. Assuming data is returned, click the Any Items radio button:
Web Chapter 1:
59
Using BDC Site Columns is the flip-side of the BDC, because it is really pulling data from an Entity into SharePoint. You may have noticed that everything mentioned previously was basically view-only and was really a matter of queries to the data then displayed in certain ways. Connections further filter this and allow the application-like functionality. In this case, however, data within columns referenced in lists are actually copied to the list and stored in SharePoint. The reason for this is that if this were a live call to the database or web service, it would result in every single item making a call. As you might imagine, as a pull, data could get out of sync. SharePoint provides a way to refresh the data on demand when viewing a list (SharePoint knows about the BDC Column and knows to make this available, as you will see later on). However, thats only part of the deal; as the developer, designer, or user, you have to make judicious use of these columns and work with data that doesnt need constant synchronization. For example, Account ID is a great candidate, because chances are that once its set, its set for good. Something like status is not so good; a constantly changing value is better served with a BDC Web Part using a live query; simply associate the list through web part connections to select the item. While not together in the same list, it serves the same purpose. Using a BDC Column is as simple as adding any column. For this example, assume you need to provide a drop-down list of Account Names in a list so that users wont have to enter them. To do this, complete the following steps: 1. In a SharePoint site, open any list or library. 2. Select List Settings. Then, from the List Settings Page, click Add Column in the Columns section. 3. On the New Column page, enter a new column with the name Account Name. 4. Under Column Types, you will now see that there is an option for Business Data. Click the radio button to select this and to show the options:
NOTE Columns added here cannot be removed; to add or remove one, the original column must first
be deleted and re-created (this can be problem as it might result in a loss of data).
60
5. Click OK to save the column, and when you return to the list, click New to create a new item. When the New Item Page appears, youll notice that the BDC Site Column appears as a lookup field:
6. As you can see, this allows the user creating the item to search for the account they want, based on the query provided in the Application. In this case, its Account City:
7. Once the account has been selected (you select by ID, if you recall; this could easily be modified to the name) and you have clicked OK, the name of the account (the column selected as the BDC Site Column) is displayed:
8. Click OK to save the item. When you return to the list, youll notice that in addition to the Site Column itself (which is clickable to view the profile), the Account City has also been included with it and the data has already been filled:
Web Chapter 1:
61
9. As I mentioned previously, BDC data may become out of date with the source. To accommodate for this, SharePoint provides an update link for the anchoring BDC Site Column: 10. Clicking this link will update all of the BDC data in the list (and any additional columns also).
62
Next, youll need to add the code to your web part, class, or application:
// BTW: You should use Try Catch around all of these! // Connect to the Shared Services Provider: SqlSessionProvider.Instance().SetSharedResourceProviderToUse(SharedServices1"); // // Attach to the Application Registry and get the Lob // system instances: NamedLobSystemInstanceDictionary LobInstances = ApplicationRegistry.GetLobSystemInstances(); // // Find the instance: LobSystemInstance CustAcctInstance = LobInstances[LOBCustomerAccountsInstance"]; // // Now you can get the entity: Entity CAEntity = CustAcctInstance.GetEntities()[CustomerAccount"]; // // Get the actual Entity instance on the key (account id): IEntityInstance CAEntInstance = CAEntity.FindSpecific(1", CustAcctInstance); // // Load the data into a data table - NOTE: this can be quite // a hit on performance depending on the data; use this only on // small tables or with limits. DataTable BDCTable = CAEntInstance.EntityAsDataTable; // // Now the data is accessible: foreach (DataRow ADataRow in BDCTable.Rows) { string AccountCity = (string)ADataRow[AccountCity"]; } //
You might think that this requires a few more lines than if you were using direct SQL and you are almost right. However, there are two major benefits: no connection string and you dont even have to create the table! One last pointer is that whenever youre working with the BDC, the order is always Shared Services Provider to LobSystemInstance to Entities. You must always have the context of the Shared Services Provider set before you can access the Application Registry objects.
Web Chapter 1:
63
than reactive. Ideally, measurements apply across the entire company, which allows a view from start to finish. For example, if there is a dramatic rise in the number of product returns, the organization can investigate the problems on the production side. (For more information on BSC, go to http://www.balancedscorecard.org/.) For example, a typical kind of indicator and metric might be to adjust the actual sales, for each sales location relative to the operational cost per square foot. This provides a measurement that can be matched against goals; if the per square foot cost increases and sales do not, it indicates that profit from that location will be affected. In enterprise terms, KPIs come from many sources: customer satisfaction, number of call backs, cost of manufacturing, revenue from services, sales by regions, and so on. The Balanced Scorecard groups these into four primary sectors: Financial This covers the objectives and otherwise money flow. Customer This covers the goals and objectives with customer satisfaction. Internal Business Processes This covers the end to end of how work is performed. Learning and Growth This covers the adaptability of the organization and people to growth. The intention is that by keeping goals and measurements against those goals (metrics) in each of these key areas, the organization can focus where it needs to. For example, financial indicators might look good (better sales and so on) but if customers are not happy, theres a good chance this wont continue. The point is to make both cause and effect visible, such as sales offset by operations. A measurement (or metric) is only good if available at both ends of the spectrum, allowing you to look at sales while being able to measure the cost of those sales. In very simple terms, KPIs are indicators of where things stand in the organization. Some KPIs are somewhat subjective, like customer satisfaction, while others are based on actual factors like cost. The measurements are based on the companys overall objectives; if the goal is to keep help desk calls low, than a low number is a green light. A higher number shows yellow, and when at an unacceptable level, it shows red. SharePoint itself doesnt provide a Balanced Scorecard Solution itself (Microsoft now has the Business Scorecard application), but what SharePoint does give you is KPI Lists These are custom lists that include the metrics (in the form of metadata) used to measure items. Data in these lists can be entered or linked to BDC data. KPI Indicator Web Parts These web parts are linked to KPI Lists and can be used to display lists of single measurement indicators (stoplights, bars, and so on), based on the levels set. The great thing about the tools in SharePoint is that it does not matter what kind of a BSC system you are using or if you are using one at all (Ive seen some done with Excel). Metrics can still be defined throughout the organization and displays can be used to monitor them. While it doesnt allow BSC reporting, it provides a wider view to a much wider audience, and I think it provides a bit more bang for the effort.
NOTE In many cases, it is desirable to use KPI Lists and Indicators in My Sites (particularly for
executives and decision makers). By default, this feature is not enabled for My Sites and must be enabled through the My Site Host Site Administration to make it available for users.
64
KPI Lists
The base of KPI functionality is in measurements, which the KPI Web Parts can then use to evaluate and compare against. Also referred to as the metrics and dimensions, the values determine the measurement points used by the KPI Web Part (what is high, low, and so on). For performance reasons, these are stored in a custom SharePoint lists call KPI Lists. Because metrics can come from multiple systems (including SharePoint), a single KPI List can retrieve the values from different sources: Indicator in a SharePoint List This means the indicator is based on data contained in a list. Indicator Using Data in an Excel Workbook This means the indicator is a cell in an Excel Workbook. Indicator Using Data in SQL Server 2005 Analysis Services This means the indicator is being pulled from a Cube value or dimension in SQL Analysis Services. Indicator Using Manually Entered Information This means the indicator is a set value.
Web Chapter 1:
65
Value Calculation This can be set to the number of items in the view as the value, a combination of one or more items can be tested against a criteria (for example, a Project Task List could be measured for a number of items showing delay and so on), or it can be based on a calculation of a single column (like sum of a specific column). For Excel: Workbook URL This is the URL of the workbook stored in SharePoint. Cell Address This is the cell in the workbook sheet to pull from (like Sheet1!A1). This can be entered manually or selected directly from the workbook using the Excel Icon. For Manual: Value This is the value to set.
Status Icon This sets the kind of indicator value. Better values Are This sets whether better is based on higher values or lower values. Display (Green) When Has Met or Exceeded Goal This sets the goal value to compare against the indicator value. It can be entered manually or selected directly from the workbook using the Excel Icon. Display (Yellow) When Has Met or Exceeded Warning This sets the warning value to compare against the indicator value. It can be entered manually or selected directly from the workbook using the Excel Icon. Display (Red) Otherwise This displays red if below (or above) the warning/ goal range. Details Link This specifies the URL of a detail page for this particular indicator (for example, the BDC Profile Page). Update Rules values): This is one of the following (does not apply to manually entered
Recalculate the Indicator Value for Every Viewer If set, this pulls the indicator data each time the KPI List is used (live). Manually Update the Value If set, this provides a link for the user to manually update the values (on demand).
66
How to build, deploy, and use SQL Analysis Services and Cubes is well outside the scope of this book, but if you intend to use SharePoint for KPIs and you have enterprise systems that can provide the data, a good understanding is well worth your time. While you likely already know what Cubes are, for those who dont, I offer a very generic definition. A Cube provides a way to view data facts based on relational dimensions of that fact as it is represented in data. For example, a fact might be Sales and the dimension of Sales might be Region:
A Cube can have multiple facts and multiple dimensions to allow modeling of what the data means in real life. A fact like Sales would have many different dimensions, such as By Store, By Region, By Quarter, and related facts such as Quotas, Commissions, and so on. The whole purpose is to provide a way to view the real-life entity of Sales by how it was created (By Store and so on), how it measures up (Quotas or Goals), things that relate to it (Commissions, Sales People, and so on), and which way it is going (Up- or Down-trend). Taking this a step further, using Cubes with multiple dimensions allows even more ways to look at the same data, for example, Sales by Quota by Salesperson. In terms of development, a cube can significantly reduce the way information in reports and so on is generated. Unlike the standard KPI indicators that set a single value, Key Performance Indicators using Cubes are based on KPIs created in the cube itself using Facts and Dimensions. The cube itself has the business logic to derive the indicator, including its Value, Goal, Status, and Trend metrics:
Web Chapter 1:
67
Once the Cube is created, it is compiled. When working as desired, it is published to the Analysis Server Database, and from there, it is available to other databases and applications. However, to use a KPI, SharePoint needs a way to connect to it, which is where the Data Connection file comes in. The Data Connection file provides all of the connection information needed by SharePoint (and to other Office programs, including InfoPath), including the authentication type, account information if needed, specific connection information (Server/Database name), and the Cube (or table) name. The great thing about these files is that once created, they can be referenced throughout SharePoint without users ever having to worry about the connection. Developers can also take advantage of these when developing Features or Solutions. Universal Data Connection files (udc or udcx) are connections based on XML. For example (note that lines are wrapped for readability; they should not be wrapped in your code):
<?Xml version="1.0" encoding="UTF-8" ?> <?MicrosoftWindowsSharePointServices ContentTypeID="0x010100B4CBD48E029A4ad8B62CB0E41868F 2B0"?> <udc:DataSource MajorVersion="2" MinorVersion="0"
68
Xmlns:udc="http://schemas.microsoft.com/office/infopath/2006/udc"> <udc:Name>Retrieve AffectedBusinessAreas</udc:Name> <udc:Description>Format: UDC V2; Connection Type: Database; Purpose: ReadOnly; Generated by Microsoft Office InfoPath 2007 on 2007-02-09 at 04:28:39 by MSPSD\SPSServices.</udc:Description> <udc:Type MajorVersion="2" MinorVersion="0" Type="Database"> <udc:SubType MajorVersion="0" MinorVersion="0" Type="" /> </udc:Type> <udc:ConnectionInfo Purpose="ReadOnly" AltDataSource=""> <udc:WsdlURL /> <udc:SelectCommand> <udc:ListId /> <udc:WebURL /> <udc:ConnectionString>Provider=SQLOLEDB.1;Integrated Security=SSPI; Persist Security Info=True;Initial Catalog=TC;Data Source=MOSSSPSDEV; Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096; Workstation ID=MOSSSPSDEV;Use Encryption for Data=False; Tag with column collation when possible=False</udc:ConnectionString> <udc:ServiceURL UseFormsServiceProxy="false" /> <udc:SoapAction /> <udc:Query>select AffectedBusinessArea" from dbo"."AffectedBusinessAreas" as AffectedBusinessAreas"</udc:Query> </udc:SelectCommand> <udc:UpdateCommand> <udc:ServiceURL UseFormsServiceProxy="false" /> <udc:SoapAction /> <udc:Submit /> <udc:FileName>Specify a filename or formula</udc:FileName> <udc:FolderName AllowOverwrite="" /> </udc:UpdateCommand> <!-- udc:Authentication> <udc:SSO AppId='' CredentialType='' /></udc:Authentication --> </udc:ConnectionInfo> </udc:DataSource>
The previous example was generated by InfoPath. Within it, you can see that it defines the database connection and what can be done with this particular data source; in this case, Select and Update. Office Data Connection (odc) files are different from udcs, because they have additional items that are specifically for Office. Fortunately, you usually dont even have to look at them because Microsoft Office and InfoPath can create them for you. One of the fastest ways to create an odc file is using Microsoft Excel 2007, since it only takes a few steps. In addition, Excel works well when dealing with Cubes, because not only can you create the connection, you can also test it by allowing Excel to display the data. Creating the odc file is done using the following steps: 1. Open Excel 2007 and then click on the Data tab in the Ribbon to view it. 2. Under the Get External Data group, click on From Other Sources, and then select the type from the drop-down menu (in the case of accessing a Cube, this would be from SQL Analysis Services, as shown):
Web Chapter 1:
69
3. Once selected, this will start the Data Connection Wizard. On the first page, enter the server name, and then select/enter the credentials needed (this is embedded so the end user need not know it). On the next page, select the database from the dropdown menu and choose the Cube (as you can see, you could also select a table). 4. Then click Next | Finish. By default, this file is saved to c:\documents and settings\ <username>\My Documents\My Data Sources (if the file already exists, you will be prompted). Next, you will be prompted where to import the data; simply click the Create Connection Only radio button and click OK. 5. You can simply copy the odc file from where Excel creates it or to export the file to save it to another location. On the Data tab under Connections, click Properties and then click the Connection Properties button. On the Definition tab, click the Export Connection File button and save the file where you like. 6. Once the file has been created, it must be uploaded to the Data Connection Library in a site that is accessible (has permissions) to the KPI List. One is usually created in MOSS sites, named either Data Connections or Local Data Connections, while one can be simply created. 7. Open the library that you want to upload the connection file to, click the Upload link in the menu, and then click Browse. Navigate to where you stored the odc file and click OK. Once the file is uploaded, the data connection can now be used anywhere in SharePoint (with appropriate permissions). To create the KPI in the KPI List: 1. From the KPI List, select New. Then from the drop-down menu, select Indicator Using the Data in SQL Server 2005 Analysis Services.
70
2. On the New KPI Indicator Page, click the icon next to the Data Connection text box, and then browse (or enter) the URL to the odc file in the Data Connection Library. Then click OK; SharePoint will automatically load the connection and provide a list of the KPIs the Cube has available. It will look something like this:
3. Once the desired KPI has been selected, the remaining information is set in a similar way to the other KPI types (notice again that you can set a Custom Detail Display Page):
Web Chapter 1:
71
4. Clicking OK will save the KPI to the list. On return to the List Display, the KPI will show as loaded and include indicators as set by the KPI in the Cube (in this example, recall that child indicators were included, so they are added to the list):
5. This information is also available when viewing the KPI. If you select View Properties from the Item drop-down menu, you can see the complete view:
72
Like any other web part, using this part is done by navigating to a page with web part zones on it, selecting Site Actions | Edit Page, clicking Add a Web Part in one of the zones shown, and then selecting Key Performance Indicators in the Add a Web Part dialog. When the part appears, it is not configured, and it provides a link to open the tool pane. Click this link to open the tool pane to set options. These settings are as follows: Indicator List This allows browsing to the KPI List (or entry of the URL) that holds the indicators. Change Icon This sets the type of display to use (lights, arrows, and so on). Show Only Status Icon This hides all but the icon (no indicator information or values are displayed). Show Only Problems This only shows issues (values that would be yellow or red). Hide the Toolbar This hides the toolbar from the display (the toolbar has links for the two previous options). Display Edit Toolbar in View Mode This hides the Edit toolbar when youre not editing. Display Multiple Indicator Columns If checked, this allows adding additional KPIs to this displaythe list items based on dimensions available in the Cube: KPI This sets the KPI item to use. Column or Dimension This sets the column or dimension to display. Hierarchy This selects the organization that will be displayed. Members to Display This enables a filter using the dimension or column. For example:
Web Chapter 1:
73
74
into two pieces: a server-side component that handles processing of Excel spreadsheets and the client-side presentation (with workbook functionality) from inside of SharePoint. When a request is made to view a spreadsheet stored in SharePoint, the request is routed to the server side. This, in turn, pulls up the workbook, handles any pre-preprocessing, establishes a data connection, and passes it off to the client for display. Since all of this requires some storage, including files, data connections, data providers, and user-defined functions, its all appropriately stored in SharePoint. Within the SSP Administration, Excel Web Services includes settings for: Services Settings These are the settings on the service itself. Trusted File Locations Libraries and file shares considered trusted for access; these are usually Document Libraries, but they can also be network file shares, folders on servers, and so on. Trusted Data Connection Libraries Data Connection Libraries considered trusted for use in spreadsheets; these can hold Universal Data Connection files and Office Data Connection files that can be used to pull data into Excel. Trusted Data Providers Defined sources (databases and so on) that can be accessed via spreadsheets either for import or reporting. User-Defined Function Assemblies External components (for example, code) that have been created for use with spreadsheets. Part of the reason for the number of settings here (for example, Trusted Data Connection Libraries) is a matter of security, but it also demonstrates that it is not part of SharePoint, simply using what SharePoint has (the same kind of definition is required in the stand-alone version).
Web Chapter 1:
75
76
Click the Add Trusted File Location link to create a new entry:
The next section applies to Session Management for this library. The settings include: Session Timeout This is the amount of time (in seconds) a session will remain open. Short Session Timeout This is the amount of time (in seconds) a session will remain open for short sessions (view). Maximum Request Duration This is the amount of time permitted for a single request (in seconds); for example, the amount of time permitted to load a single workbook or perform a single calculation. Next, Ill cover workbooks and calculation behavior:
Web Chapter 1:
77
Workbook Properties Settings include: Maximum Workbook Size This is the maximum file size in megabytes that can be opened using EWS. Maximum Chart Size This is the maximan chart size in megabytes that can be opened using EWS. Calculation Behavior Properties Settings include: Volatile Function Cache Lifetime This is the maximum time (in seconds) that a calculation function will be cached (available for reuse). Workbook Calculation Mode This sets the type of calculation mode. It includes File (calculations set as saved in the file), Manual (can be calculated on demand), Automatic (based on the workbook settings), and Automatic Except Data Tables (uses workbook settings but does not recalculate data tables). The next section sets the access to external data for workbooks in this library; settings include: Allow External Data This enables or disables access to external data; connections must be defined in Trusted Data Connection Libraries to be accessible. Warn on Refresh (like on open). If enabled, this warns the user when the data is being refreshed
Stop When Refresh on Open Fails This stops the process of opening a workbook if the external data access has failed. External Data Cache Lifetime This is the maximum time in seconds EWS will wait for a response from a query (for both Automatic and Manual). Maximum Concurrent Queries Per Session This is how many connections to external data sources are permitted in a single session. The last section either enables or disables User Defined Assemblies from being used. Click OK to save this.
78
To load this into SharePoint, the file must be saved one time to disk. This is because SharePoint doesnt load directly from Excel; it actually needs the file to be saved on a local disk and then reads it from there (this is not the case after the file has been loaded). Save the file to disk (in this case, it is named StoreSales.xlsx). Once saved, it can be loaded into SharePoint directly using the File | Save As option. In this case, the file destination is the URL of the library, and when entered, the user has a view of the library, as shown:
Web Chapter 1:
79
A few problems can occur during this process, such as a time out (which presents a general error page), but there are also a couple of specific issues that can be corrected. For example, if the user attempting to access the workbook does not have privilege to do so, they receive an error. Correcting this is done by adding the user to the site if needed and granting access to the library. If the user does have access but is not trusted, a generic error is shown (no indication at all what the error is). Correcting this is done by adding the library to the Trusted File Locations using the SSP Administration. If all is well with the data connection, the user access and library is trusted, and the document is opened in web browser as shown. As you can see, there are some key indications that EWS is running. First, you do not lose the SharePoint navigation (this is not true when a document is opened using the HTML browser). Second, the actual functionality of the sheet is provided including the menu, calculations, and sheets in the workbook.
80
2. Enter in the name for this KPI (and its description), and then either enter the workbook URL or use the Browse button:
3. To set the Excel cell values needed, click the Icon as shown previously. This will open up the workbook and allow the selection of the values:
Web Chapter 1:
81
4. As you can see, all appropriate values can be set here. Once completed, clicking OK returns to the New KPI page and the appropriate fields are filled in:
82
5. Clicking OK saves KPI, and on return to the list, shows the KPI and indicator: