<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://unfoldingneurons.com/"
	>

<channel>
	<title>SharePoint Magazine &#187; BDC</title>
	<atom:link href="http://sharepointmagazine.net/tag/bdc/feed" rel="self" type="application/rss+xml" />
	<link>http://sharepointmagazine.net</link>
	<description>SharePoint Magazine is an online Magazine dedicated to the world of SharePoint</description>
	<lastBuildDate>Mon, 05 Jul 2010 09:14:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Everything You Need to Know about BDC: Part 8 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-8-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-8-of-8#comments</comments>
		<pubDate>Mon, 08 Feb 2010 10:53:04 +0000</pubDate>
		<dc:creator>Wen He</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[BI]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[Customization]]></category>
		<category><![CDATA[Dashboards]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[platform]]></category>
		<category><![CDATA[reporting]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=3838</guid>
		<description><![CDATA[An action is simply an operation upon a selected item. The operation can retrieve information about the selected item, or it can launch a program or Web page with the selected item as a parameter.]]></description>
			<content:encoded><![CDATA[<p>Welcome back to Part 8 of our 8-part series on the Business Data Catalog (BDC). From the previous 7 installments, we have covered everything about BDC, from BDC architecture, ADF, BDC Web parts, BDC search and profile, to the BDC object model in details.  We also touched the surface of BDC actions in <a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8">Part 4</a> and <a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8">Part 5</a>. As promised, we’ll dedicate this final article to actions. We’ll explain what the BDC actions are and what they can do for you.  We’ll then walk you through how to create custom actions and how to perform these actions by using custom Web parts and InfoPath forms. As you will soon learn, this is another power capability of BDC because it extends the ability to link content to Web sites.  This allows you to quickly create mashups that are item-specific so that you can take actions in context, such as write back to your LOB systems.</p>
<p>For your reference, these are our previous seven articles:</p>
<ol>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8">Part 1</a>, BDC Purpose and technical architecture</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8">Part 2</a>, Application Definition File (ADF) and its Development</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8">Part 3</a>, Developing an ADF to Connect to Web Services</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8">Part 4</a>, Consuming Business Data through Web Parts and SharePoint Lists</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8">Part 5</a>, Implementing Enterprise Search with Business Data</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8">Part 6</a>, Integrating User Profiles with Business Data</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-7-of-8">Part 7</a>, Working with the BDC Object Model</li>
</ol>
<p>With that, let’s dive into BDC actions and start by asking what is an action.</p>
<h3>What is an action?</h3>
<p>An action is simply an operation upon a selected item. The operation can retrieve information about the selected item, or it can launch a program or Web page with the selected item as a parameter. The operation is a predefined URL link in each BDC item that enables you to act on the item, such as editing, or mapping it using Live Search as we demonstrated in Part 4.<br />
An action is composed of a URL target where the action is to occur, and the matching parameters in the URL QueryString format. When we associate an action with an entity, we can pass parameters to that action based on the contents of one or more fields. For example, in the Live Search example in Part 4, we associate the Live Search page’s URL with a customer and provide the customer’s address to parameterize the search.</p>
<p>From the above, major characteristics of actions are as follows:</p>
<ol>
<li>URL-based, parameter-driven</li>
<li>Actions on any entity and appear everywhere an entity goes</li>
<li>User can take action in ECB menu</li>
<li>Custom actions means custom code</li>
</ol>
<p>A perfect example of action is the default View Profile action, as shown in <strong>Figure 1</strong>.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb.png" border="0" alt="image" width="644" height="331" /></a><br />
Figure 1  View Profile action in a Business Data Actions Web Part</p>
<p>Through a View Profile action we can navigate to the profile page of an entity. Clicking the View Profile action in a Business Data Actions Web Part as shown in Figure 1 above, as well as in a Business Data column, or in a Business Data List Web Part, lets us view the details of an item on that item&#8217;s profile page. <strong>Figure 2</strong> shows that a Profile page that displays employee details.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image1.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb1.png" border="0" alt="image" width="299" height="484" /></a><br />
Figure 2  A Profile page that displays employee details</p>
<h4>What is a Profile page?</h4>
<p>A profile page is automatically generated for each entity that has a SpecificFinder method after BDC imports an ADF file, a profile page can display all the information from a record in the BDC.  As we’ve seen in <strong>Figure 2</strong>, a profile page can display all the fields in a record for a specific employee. The default profile page contains a BDC Item Web Part for that entity.<br />
If we put the profile page in Edit mode, there are actually two Web parts: a Business Data Item Builder and a Business Data Item that connect together. The Item Builder parses the querystring (<a href="http://win7:10001/ssp/admin/Content/Employee.aspx?EmployeeID=1)">http://win7:10001/ssp/admin/Content/Employee.aspx?EmployeeID=1)</a> and passes the EmployeeID value to the Business Data Item, which then executes the SpecificFinder method and returns a record of Employee data.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image2.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb2.png" border="0" alt="image" width="543" height="484" /></a><br />
Figure 3  Profile page components</p>
<h4>Default Profile Page and default action</h4>
<p>As we have seen from above section, the default action (View Profile) along with the default Profile page is automatically created when the entity has a SpecificFinder method.  To provide an ECB menu user experience, we can also add actions in a Business Data List Web part without using the Business Data Actions Web Part.</p>
<h4>Defining an Action</h4>
<p>There are three ways to add an action: 1) defining it in the ADF, 2) adding it in the BDC admin page after the ADF has been imported into BDC, and 3) through the BDC Object Model. Here we’re focus the first two.</p>
<h5>Defining it in the ADF</h5>
<p>To define an Action for the specified BDC entity, we’ll first locate the &lt;Actions&gt; section within the &lt;Entities&gt; and &lt;Entity&gt; hierarchy.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image3.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb3.png" border="0" alt="image" width="644" height="241" /></a><br />
Figure 4  Actions is nested within the Entities/Entity in ADF</p>
<p>And insert the &lt;action&gt; portion like this one:</p>
<p>&lt;Actions&gt;<br />
&lt;Action Name=&#8221;Update Employee&#8221; Position=&#8221;1&#8243; IsOpenedInNewWindow=&#8221;false&#8221; Url=&#8221;pages/editemployee.aspx?EmployeeID={0}&#8221; ImageUrl=&#8221;"&gt;<br />
&lt;ActionParameters&gt;<br />
&lt;ActionParameter Name=&#8221;EmployeeID&#8221; Index=&#8221;0&#8243; /&gt;<br />
&lt;/ActionParameters&gt;<br />
&lt;/Action&gt;</p>
<h5>Adding an action in the BDC admin page</h5>
<p>In the SSP administration page (View Application –&gt; View Entity), the action is defined below and the URL that takes EmployeeID as a parameter: <a href="http://dpm:10001/ssp/admin/Content/Employee.aspx?EmployeeID={0}">http://dpm:10001/ssp/admin/Content/Employee.aspx?EmployeeID={0}</a></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image4.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb4.png" border="0" alt="image" width="644" height="277" /></a><br />
Figure 5  Add an action the SSP Admin page</p>
<h4>Custom Actions</h4>
<p>We also can create custom actions for entities in BDC. Among other things, custom actions allow users to navigate to any custom page to manipulate business data.<br />
Here are some scenarios that custom actions can do:</p>
<ol>
<li>Parameterize custom search</li>
<li>Update employee in HR system</li>
<li>Customize profile page for an entity</li>
<li>Integrate BDC search into enterprise report center</li>
</ol>
<p>We’ll be creating custom actions in the last part the article.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image5.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb5.png" border="0" alt="image" width="644" height="313" /></a><br />
Figure 6 Enable View Profile action in a Business Data List Web part</p>
<p>This enables the ECB-style action, we will specify a Title property and add the following in the ADF:<br />
&lt;Entity EstimatedInstanceCount=&#8221;0&#8243; Name=&#8221;Employee&#8221;&gt;<br />
&lt;Properties&gt;<br />
&lt;Property Name=&#8221;Title&#8221; Type=&#8221;System.String&#8221;&gt;LastName&lt;/Property&gt;<br />
&lt;/Properties&gt;<br />
&lt;/Entity&gt;</p>
<p>It specifies which column in the Business Data List/Related List Web part displays the Actions menu. It also specifies the name of the TypeDescriptor that corresponds to the column you want to display as the default column in Business Data lists.</p>
<p>In the Business Data Column scenario, we can also display the action menu and link the column to the business data profile in a Business Data list.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image6.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb6.png" border="0" alt="image" width="644" height="160" /></a><br />
Figure 7  View Profile action in Business Data Column</p>
<p>This is default behavior OOB for a Business Data column.  When adding the column, just make sure the following two are checked:</p>
<ul>
<li>Display the actions menu</li>
<li>Link this column to the profile page to</li>
</ul>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image7.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb7.png" border="0" alt="image" width="644" height="410" /></a><br />
Figure 7  Enable the actions menu and profile page in Business Data list</p>
<p>These profile pages are used and being indexed by BDC Search. The following search results display the profile pages that contain the search keyword (s).  Notice in Figure 8 how a search for Great Lakes will display the profile pages for both this customer and their orders.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image8.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb8.png" border="0" alt="image" width="543" height="480" /></a><br />
Figure 8  BDC Search Results in Profile Pages</p>
<h4>Enhancing the Profile Page</h4>
<p>By default, the profile page is hosted on the Shared Services Provider site collection where the BDC administration site is located. The search result (that is, the URL) links back to the Shared Services Administration site collection address that is not scalable when you extend the Web application. In real world, we may not want to give end users access to the SSP Admin site for security reason. A better practice is to create our own profile pages and host them in any site that is not part of the SSP site collection.<br />
In this example, we’ve created a dashboard page in Report Center to replace the default Profile Page. The Report Center provides enterprise reporting capabilities that are scalable and centralized.  We can direct users to custom profile pages by updating the View Profile action.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image9.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb9.png" border="0" alt="image" width="644" height="446" /></a><br />
Figure 9  Replace the default Profile Page with Custom Report Center</p>
<p>As an alternative, we can also replace the default the URL in Action element in ADF with the path to the Profile.aspx page:</p>
<p>&lt;Actions&gt;<br />
&lt;Action Position=&#8221;1&#8243; IsOpenedInNewWindow=&#8221;false&#8221; Url=&#8221;<a href="http://reportcenter/Pages/Profile.aspx?EmployeeID={0">http://reportcenter/Pages/Profile.aspx?EmployeeID={0}&#8221;</a> ImageUrl=&#8221;/_layouts/1033/images/viewprof.gif&#8221; Name=&#8221;View Profile&#8221;&gt;<br />
&lt;ActionParameters&gt;<br />
&lt;ActionParameter Index=&#8221;0&#8243; Name=&#8221;EmployeeID&#8221; /&gt;<br />
&lt;/ActionParameters&gt;<br />
&lt;/Action&gt;<br />
&lt;/Actions&gt;</p>
<p>An action to call the Profile.aspx page for each Employee ID has been defined. This action will be the default action provides in the search result.</p>
<p>Now let’s create Profile page to display information about the Employee entity in Report Center. (The Report Center is a site that provides a central location for business-intelligence-related information.)</p>
<ol>
<li>In the <a href="http://reportcenter">http://reportcenter</a> site, create a new Blank Web Part Page called “Profile.aspx”.</li>
<li>Add the following two web parts: Query String (URL) Filter Web Part and Report Viewer Web Part.</li>
<li>Configure the Query String (URL) Filter Web Part to pickup parameter “EmployeeID” from the URL query string.</li>
<li>Configure the Report Viewer Web Part to display the employee profile report called “Employee Profile”.</li>
<li>Connect the Query String (URL) Filter Web Part parameter to the SQL Server Reporting Services Report Viewer Web Part parameter “EmployeeID”.</li>
</ol>
<blockquote><p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image10.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb10.png" border="0" alt="image" width="644" height="67" /></a><br />
Figure 10  SQL Server Reporting Services Report Viewer</p>
<p>Note: Please make sure you use this Web Part and not the OOB Report Viewer Web Part.</p></blockquote>
<p>Test that the page is picking up the URL string parameter “EmployeeID” correctly by typing the following URL: <a href="http://reportcenter/Pages/Profile.aspx?EmployeeID=108">http://reportcenter/Pages/Profile.aspx?EmployeeID=108</a></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image11.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb11.png" border="0" alt="image" width="644" height="218" /></a><br />
Figure 11  Custom Profile Page in Report Center</p>
<h4>Creating Custom Actions</h4>
<p>Creating custom actions requires custom code. The approach we take is to treat the BDC source simply as a data reader, and to build our CRUD (create/read/update/delete) logic in custom code. The BDC object model provides the means to retrieve collections, list items and enumerators, and we can use GenericInvoker to perform CRUD, which has been extensively covered in Part 7. We get the Web Parts to display data, and then we can use custom actions to create and update records by using Web parts and InfoPath Forms.</p>
<h4>Creating Web Parts</h4>
<p>We have created and deployed two Web Parts using the Object Model as shown below, with one inserting a record and one updating an existing record. (Special thanks to Lightning Tools! I’ve used <a href="http://www.lightningtools.com/bdc-meta-man/default.aspx">BDC Meta Man</a> to help with creating the Web parts.)</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image12.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb12.png" border="0" alt="image" width="467" height="480" /></a><br />
Figure 12  The two Custom Web Parts can be used to add and update employee records</p>
<p>Add these two actions in the SSP Admin page:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image13.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb13.png" border="0" alt="image" width="644" height="166" /></a><br />
Figure 13  Adding actions in the SSP Admin page</p>
<p>Now you can access the two actions from the content menu in the Employee List:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image14.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb14.png" border="0" alt="image" width="644" height="241" /></a><br />
Figure 14  Custom Actions Add Employee and Update Employee in the context menu</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image15.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb15.png" border="0" alt="image" width="644" height="342" /></a><br />
Figure 15  Add Employee Web Part</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image16.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb16.png" border="0" alt="image" width="561" height="484" /></a><br />
Figure 16  Update Employee Web Part</p>
<h4>Creating InfoPath Form</h4>
<p>MSDN has a great article titled Using Business Data Catalog Actions to Pass Parameters to InfoPath 2007 Browser Forms that walks you through this in detail.  So I’ve created our InfoPath Form and added the action using the Form Template path:<br />
<a href="http://dpm/_layouts/FormServer.aspx?XsnLocation=http://dpm/FormServerTemplates/EmployeeUpdate.xsn&amp;DefaultItemOpen=1&amp;EmployeeID={0}&amp;FirstName={1}&amp;LastName={2}">http://dpm/_layouts/FormServer.aspx?XsnLocation=http://dpm/FormServerTemplates/EmployeeUpdate.xsn&amp;DefaultItemOpen=1&amp;EmployeeID={0}&amp;FirstName={1}&amp;LastName={2}</a><br />
<a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image17.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb17.png" border="0" alt="image" width="644" height="277" /></a><br />
Figure 17  Adding Custom Action that uses InfoPath Form</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2010/02/image18.png"><img style="border-width: 0px;" src="http://sharepointmagazine.net/wp-content/uploads/2010/02/image_thumb18.png" border="0" alt="image" width="644" height="475" /></a><br />
Figure 18  Update Employee in InfoPath Form</p>
<h4>Conclusion</h4>
<p>In this final article, we have focused on actions that users can take on the business entities. We can define actions in ADF or add it “after the fact”. We have also created custom actions using the BDC object model by using custom Web parts and InfoPath forms to enable CRUD (create/read/update/delete) operation support. Once added, actions can be performed from within the list, which becomes relatively transparent to the user where the data comes from. [The statement that the BDC data is read-only is not true anymore as we have just demonstrated.] As you have learned from our 8-part series, BDC enables user interaction in business intelligence, enterprise content management, collaboration and social features, and enterprise search.</p>
<h4>Looking Forward to SharePoint Server 2010</h4>
<p>BDC has evolved to what is now called BCS (business connectivity services) in SharePoint 2010. Even though we can use BDC to enable connectivity to external systems, it was difficult to create solutions because of the lack of a designer and it was not so simple to create a solution that enabled users to make changes and write that data back to the external store. BCS now enables you to integrate LOB data into SharePoint and Office with full CRUD support, tighter integration with Office client applications, and better tools for modeling business entities. BCS is all about connecting to external data. We look forward to sharing with you the exciting new features in BCS and what they can do for you in the near future. Until then, aloha!</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-8-of-8/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 7 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-7-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-7-of-8#comments</comments>
		<pubDate>Wed, 17 Jun 2009 00:00:44 +0000</pubDate>
		<dc:creator>Wen He</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[applications]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[custom]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[lob]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[object]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=3328</guid>
		<description><![CDATA[Welcome back to Part 7 of our 8 Business Data Catalog (BDC) series. In this article, we will be focusing on the BDC Object Model.]]></description>
			<content:encoded><![CDATA[<p>Welcome back to Part 7 of our 8 Business Data Catalog (BDC) series. In this article, we will be focusing on the BDC Object Model. We start off by explaining why we would need the BDC Object Model and what it can do for us. From there we will look at some examples. Then we’ll step into the code and develop our own data access layer and custom applications to read from and write back to the LOB (line of business) systems. Finally we’ll conclude with best practices.</p>
<p>For your reference, these are our previous six articles:</p>
<ol>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8">Part 1</a>, BDC Purpose and technical architecture</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8">Part 2</a>, Application Definition File (ADF) and its Development</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8">Part 3</a>, Developing an ADF to Connect to Web Services</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8">Part 4</a>, Consuming Business Data through Web Parts and SharePoint Lists</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8">Part 5</a>, Implementing Enterprise Search with Business Data</li>
<li><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8">Part 6</a>, Integrating User Profiles with Business Data</li>
</ol>
<p>Until now, we have been working strictly with the out-of-the-box features and capabilities of BDC. MOSS Enterprise has also provided us another powerful approach for working with BDC, which is to employ the BDC Object Model and programmatically interact with a LOB system. This gives us as developers the power and control over BDC to further meet growing business needs.</p>
<p>You might be wondering why we use the BDC Object Model when you can just use ADO.NET. The reason is two-fold: 1) you already have BDC in place that has already abstracted the complexity of the business data and you want to maximize your investments, and 2) BDC takes care of authentication, authorization, and other security requirements, which is extremely helpful if you are writing a custom application that calls into a back-end system. So this makes the BDC Object Model a compelling API for us.</p>
<p>Using the BDC Object Model, we can accomplish many things such as the following examples:</p>
<ol>
<li>Auto-populate a SharePoint list that has a Business Data Column</li>
<li>Directly edit a customer in SAP</li>
<li>Synchronize content between SharePoint and an LOB system</li>
<li>Update and manipulate the ADF schema</li>
</ol>
<p>We now know what the Object Model can do so let’s first exam where the BDC Object Model fits in BDC architecturally.</p>
<h4>The BDC Object Model Overview</h4>
<p>To see where the BDC Object Model fits in the BDC world, let’s revisit the BDC architecture from <a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8">Part 1</a> with <strong>Custom Applications</strong> highlighted in <strong>Figure 1</strong>.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/06/image1.png"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://sharepointmagazine.net/wp-content/uploads/2009/06/image-thumb1.png" border="0" alt="image" width="640" height="449" /></a><br />
<strong>Figure 1 The BDC Object Model Creates Custom Applications.</strong></p>
<p>As you can see from the figure above, BDC allows developers to connect to disparate LOB systems and these systems are exposed as data sources to various MOSS features such as Web Parts, list columns, enterprise search, user profiles, and custom applications that can be developed to interface with SharePoint.</p>
<p>Custom applications can be also developed to customize and extend the existing capabilities of BDC. That’s where the BDC Object Model fits in the picture and becomes the focus of this article. The BDC Object Model provides us with new namespaces and classes (methods and properties) we can use in Visual Studio the same way we use a standard set of .NET classes and interfaces. The OOB Web Parts such as Business Data List Web Part goes through this same API that we are going to learn about. You can also create your custom Applications using the same API.</p>
<p>As we have learned already, BDC abstracts the business logic in an XML-based ADF file and stores it in a shared service provider (SSP) database. This file contains all the necessary configuration data that determines how the BDC will connect to the remote systems and which requested data to make available through the BDC Object Model. The following figure shows the interaction between the ADF and the Object Model.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/06/image3.png"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://sharepointmagazine.net/wp-content/uploads/2009/06/image-thumb3.png" border="0" alt="image" width="300" height="406" /></a><br />
<strong>Figure 2 The BDC Object Model and How It Works</strong></p>
<p>As you can see, BDC Object Model consists of <strong>Runtime</strong> and <strong>Administration</strong> object models. Each of these performs different tasks:</p>
<p>1. Runtime object model</p>
<ul>
<li>Browse metadata, execute methods, retrieve instances, traverse relationships</li>
<li>Used to build custom applications</li>
</ul>
<p>2. Administration object model</p>
<ul>
<li>Create, read, update, and delete metadata and manage permissions</li>
<li>Used to edit the metadata internally or to build metadata management tools</li>
</ul>
<h4><strong>Using the BDC Object Model</strong></h4>
<p>In order to connect to the BDC from our code, we will use the root namespace within the BDC Object model <strong>Microsoft.Office.Server.ApplicationRegistry</strong>. If you’re curious as to the term Application Registry, just know that it was the original name for BDC. It’s defined in the assembly <strong>Microsoft.sharepoint.portal.dll. </strong>Through the root namespace we have access to the child namespaces and its classes that we are going to use later in the article. Here they are listed in this table:</p>
<table class="MsoTableGrid" style="border-style: none; width: 7.65in; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="0" width="734">
<tbody>
<tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes">
<td style="border: 1pt solid black; padding: 0in 5.4pt; width: 81.7pt;" width="109" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 8pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Category</span></strong></p>
</td>
<td style="border-color: black; border-width: 1pt; border-top: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 8pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Namespace</span></strong></p>
</td>
<td style="border-color: black; border-width: 1pt; border-top: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 8pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Main Classes</span></strong></p>
</td>
<td style="border-color: black; border-width: 1pt; border-top: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 8pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Tasks</span></strong></p>
</td>
</tr>
<tr style="mso-yfti-irow: 1">
<td style="border-color: black; border-width: 1pt; border-left: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 81.7pt;" rowspan="2" width="109" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Runtime Object Model</span></strong></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">MetadataModel</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">LobSystem</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">LobSystemInstance</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Entity</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">MethodInstance</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Association</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Use it to read (and only read) the BDC objects and execute queries</span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 2">
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Runtime</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">IEntityInstanceEnumerator</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Used to manage results like a DataReader</span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 3">
<td style="border-color: black; border-width: 1pt; border-left: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 81.7pt;" width="109" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Administration Object Model</span></strong></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Administration</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">LobSystem</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">LobSystemInstance</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Entity</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Method</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">MethodInstance</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Association</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Use to create and edit the BDC objects (LOB system, entity, and method) and access control lists (ACLs) </span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 4">
<td style="border-color: black; border-width: 1pt; border-left: 1pt solid black; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 81.7pt;" rowspan="3" width="109" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><strong><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Shared (Supporting) Classes</span></strong></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Infrastructure</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">SqlSessionProvider</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">EntityInstanceIdEncoder</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">BdcAccessControlList</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Use it to manage security and connections to the database</span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 5">
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">SystemSpecific.Db</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">DbEntityInstanceEnumerator</span></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Use to manipulate entityinstances</span></p>
</td>
</tr>
<tr style="mso-yfti-irow: 6; mso-yfti-lastrow: yes">
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 88.75pt;" width="118" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><em><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">WebService*</span></em></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 201.85pt;" width="269" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Web services are part of the BDC API and layer on top of the object model and can be called remotely via the URL </span><a href="http://webapp/_vti_bin/businessdatacatalog.asmx"><span style="font-size: 7.5pt; color: #0000cc; font-family: 'Verdana','sans-serif'; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; text-underline: none">http://webapp/_vti_bin/businessdatacatalog.asmx</span></a></p>
</td>
<td style="border-style: none solid solid none; border-right: 1pt solid black; border-bottom: 1pt solid black; padding: 0in 5.4pt; width: 178.5pt;" width="238" valign="top">
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal"><span style="font-size: 7.5pt; color: black; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">Use to remotely get LOB system instances, entities, and methods</span></p>
</td>
</tr>
</tbody>
</table>
<p><strong>Table 1: Namespaces and Classes</strong></p>
<p><strong>Tip</strong>: <strong>MetadataModel</strong> and <strong>Administration</strong> use some of the same class names such as LobSystem and Entity so one way to avoid conflict when using them together is to use an alias as follows:</p>
<p>using BDCAdmin = Microsoft.Office.Server.ApplicationRegistry.Administration;</p>
<p>MSDN already has a code sample linked <a href="http://msdn.microsoft.com/en-us/library/ms492509.aspx">here</a> on how to use the <strong>Administration</strong> object model to create and import an ADF. Since it’s more practical to us, we will use the <strong>Runtime</strong> object model primarily throughout this article.</p>
<p>Now we have the basic understanding of the BDC Object Model. Let’s make use of it by applying it to the following three scenarios:</p>
<ol>
<li>Auto-populate a SharePoint list that has a Business Data Column</li>
<li>Create a BDC Utility Class that can be used in custom Applications and Web services</li>
<li>Create a custom application to update the LOB systems</li>
</ol>
<p>Since all three of these will use the Runtime object model, we can initialize our code examples by first referencing the assembly <strong>Microsoft.sharepoint.portal.dll</strong> and then import the namespaces accordingly depending on the tasks:</p>
<p>Now that namespaces have been imported, the next line of code designates the Shared Service Provider (SSP) that provides the ADF. This is accomplished using the following call to the SqlSessionProvider singleton Instance property:</p>
<p class="MsoNormal"><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">using</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> Microsoft.SharePoint;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">using</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> Microsoft.Office.Server.ApplicationRegistry.Runtime;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">using</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> Microsoft.Office.Server.ApplicationRegistry.Infrastructure;<br />
</span><span style="font-size: 10pt; color: blue; line-height: 115%; font-family: 'Courier New'; mso-no-proof: yes">using</span><span style="font-size: 10pt; line-height: 115%; font-family: 'Courier New'; mso-no-proof: yes"> Microsoft.Office.Server.ApplicationRegistry.MetadataModel;</span></p>
<p class="MsoNormal">SqlSessionProvider.Instance().SetSharedResourceProviderToUse(sspName);</p>
<p>The next set of code is the actual connection to the appropriate BDC and system instance. The connection is established by indicating the LobSystemInstance and Entity objects with the following statements:</p>
<p>LobSystemInstance lobInstance = ApplicationRegistry.GetLobSystemInstanceByName(&#8220;SynergyData&#8221;);</p>
<p>//Connect to the customers entity</p>
<p>Entity customers = lobInstance.GetEntities()["Customers"];</p>
<p>Following are the top steps we perform to call into the BDC and retrieve the data:</p>
<ol>
<li>Connect to the named SSP</li>
<li>Connect to LOB Instance</li>
<li>Connect to entity</li>
<li>Connect to method for the entity</li>
<li>Execute the method</li>
<li>Parse the results</li>
</ol>
<p>Now that you understand how to initialize your projects that use the Runtime API, let’s now examine each scenario:</p>
<h5><strong>1. Auto-populate a SharePoint list with Business Data Column</strong></h5>
<p>This application automatically populates a SharePoint list that has a Business Data Column storing customer records. First we create a SharePoint teamsite named <strong>teamsite</strong> and a SharePoint list called <strong>Customers</strong>. Then we reference both the SharePoint assembly <strong>Microsoft.SharePoint.dll</strong> and BDC assembly <strong>Microsoft.SharePoint.Portal.dll</strong>. Then code the using clauses to import the namespaces and code against the BDC Object Model by connecting to BDC and execute the method instance which will return all customers.</p>
<p>As my colleague <a href="http://www.synergyonline.com/about/professionalprofiles/Pages/RandyWilliams.aspx">Randy Williams</a> has already demoed in his <a href="http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=50">blog</a>, here’s the complete code:</p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Get SPList handle </span></span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SPSite</span> site = <span style="color: blue">new</span> <span style="color: #2b91af">SPSite</span>(<a href="http://MOSS">http:<span style="color: green">//MOSS</span></a>);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SPWeb</span> web = site.OpenWeb(<span style="color: #a31515">&#8220;teamsite&#8221;</span>);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SPList</span> customerList = web.Lists[<span style="color: #a31515">"Customers"</span>];</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connected named SSP using the following call to the SqlSessionProvider singleton instance property<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SqlSessionProvider</span>.Instance().SetSharedResourceProviderToUse(<span style="color: #a31515">&#8220;SSP&#8221;</span>);</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to the LOBSystemInstance<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">LobSystemInstance</span> lobInstance = <span style="color: #2b91af">ApplicationRegistry</span>.GetLobSystemInstanceByName(<span style="color: #a31515">&#8220;SynergyData&#8221;</span>);</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to the customers entity<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Entity</span> customers = lobInstance.GetEntities()[<span style="color: #a31515">"Customers"</span>];</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to our finder method for customers<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">MethodInstance</span> getCustomers = customers.GetFinderMethodInstance();</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Execute finder method<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">IEntityInstanceEnumerator</span> results = (<span style="color: #2b91af">IEntityInstanceEnumerator</span> ) customers.Execute(getCustomers, lobInstance);</span></p>
<p class="MsoNormal" style="margin-bottom: 0pt; line-height: normal; mso-layout-grid-align: none"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//iterate through each row returned and add a new item<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">while</span> (results.MoveNext())<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SPListItem</span> item = customerList.Items.Add();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>item[<span style="color: #a31515">"Customers_ID"</span>] = <span style="color: #2b91af">EntityInstanceIdEncoder</span>.EncodeEntityInstanceId(<span style="color: blue">new</span> <span style="color: blue">object</span>[] { results.Current[<span style="color: #a31515">"CustomerID"</span>].ToString() });<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>item.Update();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<h5><strong>2. Create a BDC Utility Class</strong></h5>
<p>We’re going to create a custom library that uses the BDC Object Model to connect to an ADF.  We treat the BDC source simply as a data reader and to build our create/update/delete logic in an assembly. The BDC object model provides the means to retrieve collections, list items and enumerators, and we do the rest. In this class, we are going to create the following three static methods:</p>
<ol>
<li>ExecuteFinder()</li>
<li>ExecuteSpecificFinder()</li>
<li>ExecuteGenericInvoker()</li>
</ol>
<p>Let’s go through the code one by one. Here’s the first static method named <strong>ExecuteFinder</strong> that returns all of the entity records.</p>
<p class="MsoNormal"><span style="font-size: 10pt; color: #4c4c4c; font-family: 'Courier New'; mso-fareast-font-family: 'Times New Roman'">namespace SharePointMag<br />
{<br />
public class BDCUtil<br />
{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">DataSet</span> ExecuteFinder(<span style="color: blue">string</span> SSPName, <span style="color: blue">string</span> LobSystemInstance, <span style="color: blue">string</span> Entity)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataSet</span> ds = <span style="color: blue">new</span> <span style="color: #2b91af">DataSet</span>(Entity);</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to named SSP<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">if</span> (SSPName != <span style="color: blue">null</span>)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SqlSessionProvider</span>.Instance().SetSharedResourceProviderToUse(SSPName);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to LOB Instance<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">LobSystemInstance</span> lobInstance = <span style="color: #2b91af">ApplicationRegistry</span>.GetLobSystemInstanceByName(LobSystemInstance);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to customers entity<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Entity</span> entity = lobInstance.GetEntities()[Entity];</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to Finder method for customers<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">MethodInstance</span> finder = entity.GetFinderMethodInstance();</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Execute Finder method<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DbEntityInstanceEnumerator</span> records = (<span style="color: #2b91af">DbEntityInstanceEnumerator</span>)entity.Execute(finder, lobInstance);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Load matching entities into a DataTable<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataTable</span> entitiesTable = <span style="color: blue">new</span> <span style="color: #2b91af">DataTable</span>();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">while</span> (records.MoveNext())<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Load each entity and include the Action URL<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DbEntityInstance</span> record = (<span style="color: #2b91af">DbEntityInstance</span>)records.Current;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataTable</span> entityTable = record.EntityAsDataTable;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>entityTable.AcceptChanges();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>entitiesTable.Merge(entityTable);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//DataTable ordersTable = customerOrders.Tables.Add(&#8220;Orders&#8221;);<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>ds.Tables.Add(entitiesTable);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">return</span> ds;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}<br />
</span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"> }<br />
</span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">}</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">The following code calls </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">ExecuteFinder of</span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"> BDCUtil class to return the customers records:</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> DataSet GetEntity()<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">return</span> <span style="color: #2b91af">BDCUtil</span>. ExecuteFinder(<span style="color: #a31515">&#8220;SSP&#8221;</span>, <span style="color: #a31515">&#8220;SynergyDataInstance&#8221;</span>, <span style="color: #a31515">&#8220;Customers&#8221;</span>);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">The following is a Web service example to call the BDCUtil class to return all the customer records:</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>[<span style="color: #2b91af">WebMethod</span>]<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: #2b91af">DataSet</span> GetCustomers()<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">string</span> SSPName=<span style="color: #a31515">&#8220;SSPPS&#8221;</span>;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">string</span> strLOBInstance=<span style="color: #a31515">&#8220;SynergyDataInstance&#8221;</span>;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">string</span> Entity=<span style="color: #a31515">&#8220;Customers&#8221;</span>;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataSet</span> ds = <span style="color: blue">new</span> <span style="color: #2b91af">DataSet</span>(Entity);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>ds = <span style="color: #2b91af">BDCUtil</span>. ExecuteFinder(SSPName, strLOBInstance, Entity);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">return</span> ds;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">Note: For simplicity, we explicitly pass in the name of LOB Instance and Entity in our examples. They could also be “discovered” if you desire. Please check out this </span><a href="http://msdn.microsoft.com/en-us/library/ms568510.aspx"><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">MSDN</span></a><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes"> article titled <em>How to: Get Started with Using the Runtime Object Model</em>.</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">The second method named </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">ExecuteSpecificFinder returns a single row of record identified by its ID.</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: #2b91af">DataSet</span> ExecuteSpecificFinder(<span style="color: blue">string</span> SSPName, <span style="color: blue">string</span> LobSystemInstance, <span style="color: blue">string</span> Entity, <span style="color: blue">object</span>[] parameters)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataSet</span> ds = <span style="color: blue">new</span> <span style="color: #2b91af">DataSet</span>(Entity);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to named SSP<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">if</span> (SSPName != <span style="color: blue">null</span>)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SqlSessionProvider</span>.Instance().SetSharedResourceProviderToUse(SSPName);<span style="mso-spacerun: yes"> </span></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">try<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to LOB Instance<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">NamedLobSystemInstanceDictionary</span> lobInstances = <span style="color: #2b91af">ApplicationRegistry</span>.GetLobSystemInstances();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">LobSystemInstance</span> lobInstance = lobInstances[LobSystemInstance];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Entity</span> entity = lobInstance.GetEntities()[Entity];</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Get the specific mathcing record<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DbEntityInstance</span> record = (<span style="color: #2b91af">DbEntityInstance</span>)entity.FindSpecific(parameters, lobInstance);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Loading matching entity into DataTable<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">DataTable</span> entityTable = record.EntityAsDataTable;</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Return the results as a dataset</span></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//DataSet ds = new DataSet(Entity);<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>ds.Tables.Add(entityTable);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">return</span> ds;<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">The following code calls the ExecuteSpecificFinder of BDCUtil class to return one row of employee record.</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">public</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> <span style="color: blue">static</span> <span style="color: #2b91af">DataSet</span> ExecuteSpecificFinder()<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">object</span>[] parameters = <span style="color: blue">new</span> <span style="color: blue">object</span>[1];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[0] = 1; <span style="color: green">//Employee ID;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">return</span> <span style="color: #2b91af">BDCUtil</span>.ExecuteSpecificFinder(<span style="color: #a31515">&#8220;SSP&#8221;</span>, <span style="color: #a31515">&#8220;SynergyDataInstance&#8221;</span>, <span style="color: #a31515">&#8220;Employees&#8221;</span>, parameters);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">This is the returned employee record that’s displayed in XML format:</span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; color: blue; font-family: consolas">&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Employees</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;<br />
</span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Employees</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;<br />
</span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">EmployeeID</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">1<span style="color: blue">&lt;/</span><span style="color: #a31515">EmployeeID</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">LastName</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Davolio<span style="color: blue">&lt;/</span><span style="color: #a31515">LastName</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">FirstName</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Nancy<span style="color: blue">&lt;/</span><span style="color: #a31515">FirstName</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Title</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Sales Representative<span style="color: blue">&lt;/</span><span style="color: #a31515">Title</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">TitleOfCourtesy</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Ms.<span style="color: blue">&lt;/</span><span style="color: #a31515">TitleOfCourtesy</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">BirthDate</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">12/8/1948 12:00:00 AM<span style="color: blue">&lt;/</span><span style="color: #a31515">BirthDate</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">HireDate</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">5/1/1992 12:00:00 AM<span style="color: blue">&lt;/</span><span style="color: #a31515">HireDate</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Address</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">507 &#8211; 20th Ave. E.</span><span style="font-size: 9.5pt; font-family: consolas">Apt. 2A<span style="color: blue">&lt;/</span><span style="color: #a31515">Address</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">City</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Seattle<span style="color: blue">&lt;/</span><span style="color: #a31515">City</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Region</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">WA<span style="color: blue">&lt;/</span><span style="color: #a31515">Region</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">PostalCode</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">98122<span style="color: blue">&lt;/</span><span style="color: #a31515">PostalCode</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Country</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">USA<span style="color: blue">&lt;/</span><span style="color: #a31515">Country</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">HomePhone</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">(206) 555-9857<span style="color: blue">&lt;/</span><span style="color: #a31515">HomePhone</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Extension</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">5467<span style="color: blue">&lt;/</span><span style="color: #a31515">Extension</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Photo</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">FRwvAAIAAAA…truncated…&lt;/<span style="color: #a31515">Photo</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Notes</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">Education includes a BA in psychology from Colorado State University in 1970.<span style="mso-spacerun: yes"> </span>She also completed &#8220;The Art of the Cold Call.&#8221;<span style="mso-spacerun: yes"> </span>Nancy is a member of Toastmasters International.<span style="color: blue">&lt;/</span><span style="color: #a31515">Notes</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">ReportsTo</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">2<span style="color: blue">&lt;/</span><span style="color: #a31515">ReportsTo</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">PhotoPath</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">http://portal.synergy.com/hr/employeephotos/ndavolio.jpg<span style="color: blue">&lt;/</span><span style="color: #a31515">PhotoPath</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">LoginAccount</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; font-family: consolas">synergy\ndavolio<span style="color: blue">&lt;/</span><span style="color: #a31515">LoginAccount</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 9.5pt; color: blue; font-family: consolas"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 9.5pt; color: #a31515; font-family: consolas">Employees</span><span style="font-size: 9.5pt; color: blue; font-family: consolas">&gt;</span><span style="font-size: 9.5pt; color: blue; font-family: consolas"> </span></p>
<p class="MsoNormal"><span style="font-size: 9.5pt; font-family: consolas">Note: The &lt;Photo&gt; element has been truncated to save space here.</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">Now let’s move on to <strong>GenericInvoker </strong>by </span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">adding <strong>ExecuteGenericInvoker </strong>method in our BDCUtili class</span><strong><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">.</span></strong><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes"> The <a><strong>ExecuteGenericInvoker</strong> method calls the GenericInvoker method instance to write back to LOB systems.</a></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> ExecuteGenericInvoker(<span style="color: blue">string</span> SSPName, <span style="color: blue">string</span> lobSystemInstance, <span style="color: blue">string</span> entityName, <span style="color: blue">string</span> methodInstance, <span style="color: blue">object</span>[] parameters)</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">{</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//Connect to named SSP<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">if</span> (SSPName != <span style="color: blue">null</span>)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">SqlSessionProvider</span>.Instance().SetSharedResourceProviderToUse(SSPName);</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">NamedLobSystemInstanceDictionary</span> instances = <span style="color: #2b91af">ApplicationRegistry</span>.GetLobSystemInstances();<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">LobSystemInstance</span> instance = instances[lobSystemInstance];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Entity</span> entity = instance.GetEntities()[entityName];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">MethodInstance</span> methInst = entity.GetMethodInstances()[methodInstance];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>entity.Execute(methInst, instance, <span style="color: blue">ref</span> parameters);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">In our third example,</span><span style="font-size: 10pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes"> we look at </span><strong><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">GenericInvoker </span></strong><span style="font-size: 8pt; font-family: 'Verdana','sans-serif'; mso-bidi-font-family: 'Courier New'; mso-no-proof: yes">and then call the</span><strong><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"> ExecuteGenericInvoker </span></strong><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">method we’ve just added.</span></p>
<h4><strong><span style="font-size: 12pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">3. Create a Custom Application to Update the LOB systems</span></strong></h4>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">BDC is very well known as read-only tool. <span style="mso-spacerun: yes"> </span>It’s read-only because the OOB functionality does not make use of <strong>GenericInvoker</strong> methods. However, the object model and ADF support this type of method instance that we invoke just as we would invoke any other method. If you think of this as a stored procedure call and if I can call a stored procedure that runs a select statement, I should be able to call a stored procedure that inserts or updates as long as the underlining data repository supports them. In other words, the <strong>GenericInvoker</strong> method allows us to call other SQL commands. For our situation, we’ll use it to write back to our back-end system.<span style="mso-spacerun: yes"> </span></span></p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">So let’s first add the <strong>GenericInvoker</strong> method in our ADF file and then call the <strong>ExecuteGenericInvoker </strong>method in our BDCUtil class . (Note: I’ve used </span><a href="http://www.lightningtools.com/bdc-meta-man/default.aspx"><span style="font-size: 8pt; color: #0000cc; font-family: 'Verdana','sans-serif'; text-decoration: none; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; text-underline: none">BDC Meta Man</span></a><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"> to help generate the ADF and create ExecuteGenericInvoker. Thanks Lightning Tools! If you use BDC Definition Editor, you cannot select byte array <em>byte[]</em> as the return type of the field. You can instead select <em>byte</em> and edit the ADF by hand by changing <em>byte</em> to <em>byte[].</em>)  The following is the ADF and for the purpose of this example, only a single entity called Employees has been defined. </span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> &lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Entity</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">EstimatedInstanceCount</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">0</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Identifiers</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Identifier</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">EmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Identifiers</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Methods</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Methods</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Entity</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">insertEmployees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandText</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>Insert into Employees(LastName,FirstName,Title) Values(@LastName,@FirstName,@Title);select NewEmployeeID = SCOPE_IDENTITY()<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandType</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;</span>Text<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@LastName</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">LastName</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@FirstName</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">FirstName</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@Title</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Title</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">Return</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">NewEmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstance</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">EmployeesInserter</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">GenericInvoker</span>&#8220;<span style="color: blue"> </span><span style="color: red">ReturnParameterName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">updateEmployees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandText</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;</span>Update Employees SET LastName=@LastName,FirstName=@FirstName,Title=@Title WHERE(EmployeeID=@EmployeeID)<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandType</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;</span>Text<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@EmployeeID</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">EmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@LastName</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">LastName</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@FirstName</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">FirstName</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@Title</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Title</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">Return</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">EmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstance</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">EmployeesUpdater</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">GenericInvoker</span>&#8220;<span style="color: blue"> </span><span style="color: red">ReturnParameterName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">deleteEmployees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandText</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;</span>Delete Employees WHERE(EmployeeID=@EmployeeID)<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Property</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">RdbCommandType</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">System.String</span>&#8220;<span style="color: blue">&gt;</span>Text<span style="color: blue">&lt;/</span><span style="color: #a31515">Property</span><span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Properties</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">In</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">@EmployeeID</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">EmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Direction</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">Return</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue">&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">TypeDescriptor</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">TypeName</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">System.Int32</span>&#8220;<span style="color: blue"> </span><span style="color: red">Name</span><span style="color: blue">=</span>&#8220;<span style="color: blue">EmployeeID</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameter</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Parameters</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstance</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"> </span><span style="font-size: 10pt; color: red; font-family: 'Courier New'; mso-no-proof: yes">Name</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">=</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">&#8220;<span style="color: blue">EmployeesDeleter</span>&#8220;<span style="color: blue"> </span><span style="color: red">Type</span><span style="color: blue">=</span>&#8220;<span style="color: blue">GenericInvoker</span>&#8220;<span style="color: blue"> </span><span style="color: red">ReturnParameterName</span><span style="color: blue">=</span>&#8220;<span style="color: blue">Employees</span>&#8220;<span style="color: blue"> /&gt;<br />
</span></span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">MethodInstances</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;<br />
</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>&lt;/</span><span style="font-size: 10pt; color: #a31515; font-family: 'Courier New'; mso-no-proof: yes">Method</span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">&gt;</span></p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">I’ve created three GenericInvoker MethodInstances and they are </span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">EmployeesInserter,EmployeesUpdater</span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">, and </span><span style="font-size: 10pt; color: blue; font-family: 'Courier New'; mso-no-proof: yes">EmployeesDeleter.</span><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'"> When a method instance is executed, it will eventually call the appropriate SQL command as shown here:</span></p>
<ul>
<li>
<div class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">Insert into Employees(LastName,FirstName,Title) Values(@LastName,@FirstName,@Title);select NewEmployeeID = SCOPE_IDENTITY()</span></div>
</li>
<li>
<div class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">Update Employees SET LastName=@LastName,FirstName=@FirstName,Title=@Title WHERE(<a href="mailto:EmployeeID=@EmployeeID">EmployeeID=@EmployeeID</a>)</span></div>
</li>
<li>
<div class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes">Delete Employees WHERE(EmployeeID=@EmployeeID)</span></div>
</li>
</ul>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">The following method ExecuteGenericInvoker is to call the GenericInvoker method:</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> InsertEmployee()</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">object</span>[] parameters = <span style="color: blue">new</span> <span style="color: blue">object</span>[3];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[0] = <span style="color: #a31515">&#8220;He&#8221;</span>; <span style="color: green">//Last Name;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[1] = <span style="color: #a31515">&#8220;Wen&#8221;</span>; <span style="color: green">//First Name;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[2] = <span style="color: #a31515">&#8220;SharePoint Architect&#8221;</span>; <span style="color: green">//Title;</span></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">try<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">BDCUtil</span>.ExecuteGenericInvoker(<span style="color: #a31515">&#8220;SSP&#8221;</span>, <span style="color: #a31515">&#8220;SynergyDataInstance&#8221;</span>, <span style="color: #a31515">&#8220;Employees&#8221;</span>, <span style="color: #a31515">&#8220;EmployeesInserter&#8221;</span>, parameters);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> exception)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Console</span>.WriteLine(exception.ToString());<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p>The result is as you can see here highlighted:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/06/clip-image002.jpg"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://sharepointmagazine.net/wp-content/uploads/2009/06/clip-image002-thumb.jpg" border="0" alt="clip_image002" width="640" height="189" /></a></p>
<p>In the same token, the following code will update the employee record:</p>
<p class="MsoNormal"><span style="font-size: 8pt; color: #4c4c4c; font-family: 'Verdana','sans-serif'; mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'">In the same token, the following code will update the employee record:</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">public</span> <span style="color: blue">static</span> <span style="color: blue">void</span> UpdateEmployee()<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">object</span>[] parameters = <span style="color: blue">new</span> <span style="color: blue">object</span>[4];<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: green">//The parameters must match the parameters defined in ADF<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[0] = <span style="color: #a31515">&#8220;10&#8243;</span>; <span style="color: green">//Employee ID;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[1] = <span style="color: #a31515">&#8220;He&#8221;</span>; <span style="color: green">//Last Name;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[2] = <span style="color: #a31515">&#8220;Wen&#8221;</span>; <span style="color: green">//First Name;<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>parameters[3] = <span style="color: #a31515">&#8220;MOSS Architect&#8221;</span>; <span style="color: green">//Title;<br />
</span></span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">try<br />
</span></span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">BDCUtil</span>.ExecuteGenericInvoker(<span style="color: #a31515">&#8220;SSP&#8221;</span>, <span style="color: #a31515">&#8220;SynergyDataInstance&#8221;</span>, <span style="color: #a31515">&#8220;Employees&#8221;</span>, <span style="color: #a31515">&#8220;EmployeesUpdater&#8221;</span>, parameters);<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p class="MsoNormal"><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: blue">catch</span> (<span style="color: #2b91af">Exception</span> exception)<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>{<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span><span style="color: #2b91af">Console</span>.WriteLine(exception.ToString());<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}<br />
</span><span style="font-size: 10pt; font-family: 'Courier New'; mso-no-proof: yes"><span style="mso-spacerun: yes"> </span>}</span></p>
<p>Result is as follows:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/06/clip-image004.jpg"><img style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" src="http://sharepointmagazine.net/wp-content/uploads/2009/06/clip-image004-thumb.jpg" border="0" alt="clip_image004" width="640" height="191" /></a></p>
<p>Note: the order of the parameters must match that of the parameters defined in the updateEmployees method in the ADF. The ReturnParameterName (ReturnParameterName=&#8221;Employees&#8221;) is required in the EmployeeUpdater and EmployeeDeleter MethodInstance, even though they have no parameters to return.</p>
<p>As we have just learned, the <strong>GenericInvoker </strong>method is extremely useful because it takes care of authentication and authorization while enabling our custom applications to call in and execute business logic stored in the back-end to insert/update/delete LOB systems.</p>
<h5><strong>Write-back Best Practice</strong></h5>
<p>Even though BDC can update the LOB systems, it’s not suited for all scenarios. I strongly recommend you to take it into consideration governance and change management that your organization might require. Here are some additional best practices:</p>
<ol>
<li>Understand the vendor support implications for changes that you make. For example, directly querying SharePoint databases is not Microsoft supported because the risk involved in damaging it.</li>
<li>Understand data integrity rules before using GenericInvoker method to make direct changes.</li>
<li>Have error handling in place.</li>
<li>When full inserts and updates are needed, consider using the LOB vendor’s own API that provides transactional write-back capabilities from the client to the underlying LOB application. Another way this can be done is using custom actions which will be covered in detail in Part 8.</li>
</ol>
<h4><strong>Conclusion</strong></h4>
<p>BDC Object Model provides a new and exciting solution by allowing direct integration with LOB systems. In this article we have explored the BDC Object Model and exploited the capabilities of the BDC from code. BDC encapsulates the business logic of the back-end systems and developers can just work with the BDC objects to interact with those systems. We’ve demonstrated how to retrieve customer records to populate a SharePoint list that has a BDC data column, and then created a BDC utility class to act as a data layer, finally called the utility class to update the back-end system. With this you can now develop custom applications to interface with SharePoint using the BDC Object Model.  And for organizations that have invested in BDC, you are on your way to leveraging the real power of BDC!</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-7-of-8/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 6 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8#comments</comments>
		<pubDate>Sun, 19 Apr 2009 20:44:53 +0000</pubDate>
		<dc:creator>Randy Williams</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[Active Directory]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[User Profiles]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=2466</guid>
		<description><![CDATA[In this article, the focus will be on configuring User Profiles to import properties from external systems via the BDC.]]></description>
			<content:encoded><![CDATA[<p>Greetings and welcome to Part 6 of our Business Data Catalog (BDC) Series.  In this article, the focus will be on configuring User Profiles to import properties from external systems via the BDC.  I’ll start off by giving you a good grounding in the overview section.  I’ll then jump into creating the two different types of import connections, 1:1 and 1:many, and then show you in detail how to map your profile properties.   Finally, I’ll wrap up with some troubleshooting tips.  By the end, you’ll have a solid understanding of how to configure your ADFs and User Profiles to import and map your properties.</p>
<p>In case you’re just joining us in the series, here are our previous five articles:</p>
<p><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8" target="_blank">Part 1</a>.  BDC Purpose and technical architecture</p>
<p><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8" target="_blank">Part 2</a>.  Detailed overview of the Application Definition File (ADF) and how to develop one to connect to a back-end database</p>
<p><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8" target="_blank">Part 3</a>.  Developing an ADF to connect to Web Services</p>
<p><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8" target="_blank">Part 4</a>.  Consuming Business Data through Web Parts and SharePoint lists</p>
<p><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8" target="_blank">Part 5</a>.  Implementing Enterprise Search with Business Data</p>
<h4>Overview</h4>
<p>User Profiles within MOSS are a great way to store key information about SharePoint users.  This information, stored within individual profile properties, contains useful content such as first name, last name, date of hire, the user’s manager, and numerous personal details such as interests and skills.  This user metadata can be used when executing workflow, searching for people, utilizing social networking aspects such as my sites, defining audiences, any many other SharePoint capabilities.  SharePoint contains dozens of built-in properties, and you can add any custom properties as needed.</p>
<p>While all of this a great benefit to enhancing SharePoint’s knowledge of these people, there may be a drawback to this.  Here is yet another database of information that needs to be populated!  In most organizations some of this information lives within Active Directory (AD) and perhaps other details can be found in repositories such as HR systems, so you can say that SharePoint is really just duplicating what already exists elsewhere.  The primary goal of this article is to show you how you can eliminate this redundant data entry by pulling this authoritative information from your external systems through the BDC.</p>
<p>User Profiles and the profile properties are all maintained within your Shared Services Provider (SSP).  User profiles can be created manually, or you can create import connections which allows you to automatically synchronize these values from external systems.  Supported external systems are AD, LDAP (such as Lotus Notes), and BDC.</p>
<p>An important detail you must understand is that only AD or LDAP can be set up as a primary (or master) connection.  A BDC connection cannot be.  A primary connection means that a SharePoint profile with an account name (e.g. domain\username) can be created from this source.  BDC can only be a secondary connection, meaning that it is only able to fill in additional properties for an existing profile—in other words, it cannot create a profile.</p>
<p>To better explain, see Figure 1 below which shows the profile being created (based on the Account name) from AD and additional properties coming from an HR System (click image to enlarge):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image24.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb24.png" border="0" alt="image" width="404" height="294" /></a></p>
<p><strong>Figure 1: Mapping profile properties between SharePoint and external systems</strong></p>
<p>The arrows reflect the mapping between SharePoint profile properties and columns in external systems.  You can see that some information (such as first and last name) may be duplicated in external systems.  When defining mapping for a profile property, you can only specify a single source for the data.  Based on the arrows, the decision was made to pull the first and last name from AD.</p>
<p>For many organizations, this is a common scenario.  AD, maintained by the IT group, typically contains only a minimal amount of accurate user meta data.  Other systems, often maintained by the HR group, contains additional values.  SharePoint allows you to set up multiple primary and secondary connections to ensure all your profiles can be created and populated as needed.</p>
<p>Now that you have a basic understanding, the rest of the article will focus on how to create and configure these secondary BDC import connections.</p>
<h4>Creating BDC Import Connections</h4>
<p>Prior to creating a BDC Import Connection, I recommend you configure and ensure that your AD or LDAP primary connection is functioning.  Once this is working, you can then focus on your secondary BDC connection.  For my upcoming demos that I’ll walk you through, I am pulling accounts from a single domain inside AD.</p>
<p>To create a BDC Import connection, first access your User Profile and Properties screen within your SSP (Central Administration –&gt; SSP –&gt; User profiles and properties).  On this screen, click on the View Import Connections link.  Then click on the Create New Connection toolbar button.  Finally, choose Business Data Catalog type in the drop down list.  This will yield the following screen:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image7.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb7.png" border="0" alt="image" width="504" height="356" /></a><br />
<strong>Figure 2: Creating a BDC Import Connection </strong></p>
<p>In Figure 2 above, you’ll notice that you have two mapping options (depicted by the radio buttons),  1:1 and 1:many.  Let’s look at each option in detail:</p>
<h4>1:1 Import Connection Type</h4>
<p>A 1:1 connection is the most common type of connection that is used.  This means that a single profile in SharePoint will map to a single entity record that is returned from BDC.  For example, if we have a user profile for synergy\afuller as shown in Figure 1 above, this user will also exist in an external system.  For a 1:1 mapping, a Specific Finder method will be called based on the selected entity.  This shouldn’t surprise you as a Specific Finder method returns a single record from the external system.  A good question you might be thinking is how does it know which record to pull?  I’ll answer this question as I show you how to configure the connection.</p>
<p>To configure the 1:1 mapping as shown in Figure 2, we need to first start off by creating or identifying an existing profile property that can be used to uniquely identify the user in the external system.  This property must also match the identifier that is defined for your entity in your ADF.  In my example, I will be using EmployeeID which is the primary key for an Employees table in a SQL Server database.  Employees represents a table usually found in HR or ERP systems.  Here is the Identifier as reflected in the ADF:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image8.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb8.png" border="0" alt="image" width="404" height="61" /></a><br />
<strong>Figure 3: EmployeeID as the Identifier for Employees Entity</strong></p>
<p>And here is the Specific Finder:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image9.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb9.png" border="0" alt="image" width="534" height="103" /></a><br />
<strong>Figure 4: Specific Finder for Employees Entity</strong></p>
<p>As you can see, I have selected EmployeeID to be the unique identifier.  Since I don’t have a built-in profile property in SharePoint that stores EmployeeID, I’ll create one.  This is necessary for the 1:1 mapping to work.  Here is how it looks after I’ve created it:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image10.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb10.png" border="0" alt="image" width="346" height="60" /></a><br />
<strong>Figure 5: Newly Created EmployeeID Profile Property</strong></p>
<p>I chose the integer type because the property’s type must be compatible with the type defined in the Identifier (which was defined as System.Int32 as shown in Figure 3).</p>
<p>Now that this is done, I can create my BDC Import connection.  (Note: Even though you are only creating a 1:1 mapping that will use a Specific Finder, this screen also expects a Finder method.  Even though the Finder method is only used when creating 1:Many connections as discussed below, you must still have one or you will get an error when you select the entity from the catalog in this screen.)</p>
<p>Going back from Figure 2 above, after selecting Business Data Catalog as the type, you must enter a connection name.  I recommend a friendly name that you’ll easily recognize. For my demo, since I’m pulling employee information from an HR system, I’ll call the connection HREmployee.  Here is how it looks just prior to saving:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image11.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb11.png" border="0" alt="image" width="334" height="306" /></a><br />
<strong>Figure 6: Creating a 1:1 Import Connection</strong></p>
<p>You’ll notice that I selected the EmployeeID profile property that was just created.  For this to work, I now need to go into my current SharePoint profiles and manually enter in a values for EmployeeID.  This is necessary in my example since SharePoint must know what value to pass to the Specific Finder.  If you’re using a built-in profile property that is already populated (such as the Account name), you don’t need to do this.</p>
<p>Now that the 1:1 relationship between the User Profile and the external system is set up, it’s time to figure out which profile properties you want to import.  If you refer back to Figure 1 above, you’ll see that I illustrate the importing of Title and About me properties from the external system.</p>
<p>For the demo here, I’ll map two existing properties, Hire Date and About me.  You do this by editing the profile property (SSP –&gt; User profile and properties –&gt; View profile properties –&gt; Choose a property and edit).  There’s no reason why I can’t create new properties and map these; the process is the same.  Here is how to map the Hire date profile property to the HireDate column from the HREmployees import connection:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/clip-image001.gif"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/clip-image001-thumb.gif" border="0" alt="clip_image001" width="525" height="345" /></a><strong><br />
Figure 7: Mapping Hire Date</strong></p>
<p>Figure 7 above shows the upper and lower portion of the same screen.  When choosing a column in the Data source field to map drop down list, you’ll be presented with a list of all the columns returned from the Specific Finder.  So, the rule of thumb is the ensure that you are returning all columns you want to map from your Specific Finder.  As with creating the import connection, when mapping properties this way, you must ensure the data types are compatible.  If they are not, you’ll be given an error message like this: <em>Cannot map to this data source field. This property is of type &#8216;date&#8217; and the data source field you are mapping to is of type &#8216;System.String&#8217;</em>.</p>
<p>I have also mapped the About me property to the Notes column defined in the Specific Finder.  At this point, the mapping configuration is in place.  We’re not quite done yet, however.</p>
<p>Another important step is to ensure that your Default Content Access Account has permissions to update these profile properties through the BDC.  The Default Content Access Account is configured when setting up Enterprise Search (SSP –&gt; Search settings –&gt; Default content access account).  If you prefer, you can also set a specific account when configuring the User Profile Import.  Just go to SSP –&gt; User profile and properties –&gt; Default access account.  Now that you know what your access account is, you must grant this account two sets of permissions:  1) Permissions to update your profile properties and 2) permissions to call into these BDC methods.</p>
<p>To grant permissions to update profile properties, go to SSP –&gt; Personalization services permissions.  On this screen, grant your access account the Manage User Profiles permission as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image13.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb13.png" border="0" alt="image" width="384" height="236" /></a><br />
<strong>Figure 8: Granting Content Access Account Manage User Profiles Permissions</strong></p>
<p>If you’ve worked much with profile properties, you’ve probably noticed that each property can be individually secured by adjusting its privacy setting.  The Manage User Profiles permission grants my access account (SYNERGY\MOSS.Search) write permissions to all profile properties.  Without this, you’ll need to set the privacy level of each mapped property to Everyone, which may not be the best security level.</p>
<p>The second permission is to grant this access account permissions to the BDC entity.  If you’ve been following our series, we covered BDC permissions in <a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8" target="_blank">Part 2</a>.  The minimum permission you need to grant is Execute as shown below.  You access this screen from SSP –&gt; View Applications –&gt; &lt;Select ADF&gt; –&gt; &lt;Select entity&gt; –&gt; Manage Permissions.  In this screen shot, I grant MOSS.Search execute permissions to the Employees entity:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image14.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb14.png" border="0" alt="image" width="464" height="165" /></a><br />
<strong>Figure 9: Granting Access Account Entity Permissions in BDC</strong></p>
<p>Finally, we are now done and ready to import.  Let’s quickly recap to make sure we have these steps down.  Again, we’re talking about a 1:1 mapping.</p>
<p>1.  Ensure ADF is prepared with a Specific Finder returning the columns you want to map.</p>
<p>2.  Create a new or choose an existing profile property that contains values to match the entity identifier.  In my example above, I used EmployeeID.</p>
<p>3.  Create a 1:1 import connection.</p>
<p>4.  Map your desired profile properties to columns returned from Specific Finder.</p>
<p>5.  Grant your content access account permissions</p>
<p>To start the import, return to the main User Profiles screen and click Start full import.  This will first do a full import from your primary import connection.  The status here is reflected next to Profile import status shown below.  Once that is done (and sometimes with a brief minute or two delay after it finishes), the secondary imports from BDC will begin.  This is reflected next to Membership &amp; BDC import status.  Both are shown highlighted here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image15.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb15.png" border="0" alt="image" width="524" height="262" /></a><br />
<strong>Figure 10: User Profile import status</strong></p>
<p>Once the profile imports complete (and it may take from several minutes to possibly an hour for thousands of users), you’ll want to check the import log to get a sense on whether it succeeded.  To do so, click the View import log link.  When reading the log, you should know that a PEOPLE_IMPORT content source refers to individual person crawls through your primary import connection, whereas PEOPLE_DL_IMPORT refers to group (i.e. distribution list) crawls.  PEOPLE_DL_IMPORT is also where your secondary import connections through BDC are logged, so it’s relevant to us in the scope of this article.  Here is a part of the log showing both content sources for one user, Andrew Fuller.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image16.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb16.png" border="0" alt="image" width="604" height="76" /></a><br />
<strong>Figure 11: User Profile Import Log</strong></p>
<p>Even though the logs may look fine, you’ll certainly want to verify some of the mapped values come over.  To view one, simply click on View user profiles and select a user.  In Figure 11 below, here are the two mapped properties for synergy\afuller:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/clip-image00191.gif"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/clip-image0019-thumb1.gif" border="0" alt="clip_image001[9]" width="500" height="221" /></a><strong><br />
Figure 12: About me and Hire date values pulled in by profile import</strong></p>
<p>Since I mapped the About me property, you can also see this within the user’s My Profile found in their My site.  Here is Andrew Fuller’s:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image18.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb18.png" border="0" alt="image" width="504" height="166" /></a><br />
<strong>Figure 13: Andrew Fuller’s My Profile page</strong></p>
<p>Now that you have a solid overview of 1:1 mappings, let’s turn our attention to 1:many.</p>
<h4>1:Many Import Connection Type</h4>
<p>While less common than 1:1 connections, a 1:many is handy in a few situations.  Let me give you one example.  As mentioned in the overview section above, the IT group typically manages basic user attributes in AD.  In all my years of consulting, I’ve encountered very few organizations that actually keep these attributes up to date.  The problem is that IT is usually busy handing a myriad of critical problems, and they don’t usually bother updating less important attributes such as someone’s manager.  As long as the permissions are right, that’s what is important to them.</p>
<p>This can cause problems, however.  One of the useful SharePoint profile properties is Manager which gives SharePoint knowledge of the organizational hierarchy.  This was shown in Figure 13 above when looking at Andrew Fuller’s My Profile page.  By default, this property is mapped to the manager setting for the user in AD.  However, if this value is not set or out of date, SharePoint won’t have an accurate picture of the organization.</p>
<p>To correct this problem, we will pull the manager from a Departments table that is stored in our external HR system.  Here is where the 1:many comes in.  Recognize that many users will have the same department.  The idea is that we want to use the department profile property in SharePoint, which is correctly set, and use that to look up into the Departments table (in the external system) to pull the manager for that department.  So, you can think of the 1:many to be for each department there will be many user profiles with that value.</p>
<p>Let me show you how I configure the mapping to pull the Manager property from our HR System.  I start off by adding another Import connection.  Yes, you can have multiple import connections coming from BDC.  I call this one HREmployeesGetManager and here is how it is configured:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image19.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb19.png" border="0" alt="image" width="354" height="323" /></a><br />
<strong>Figure 14: Creating a 1:many import connection</strong></p>
<p>When choosing the 1:many mapping radio button, you have two drop downs to fill in.  You first need to select the filter.  The choices you have will be the filter descriptors that have been made available for the entity’s Finder method.  Hence, to use 1:many mapping, you must have a finder method and at least one filter descriptor.  (Note: if you cannot select 1:many mapping, it is probably because you don’t have filter descriptors defined in your ADF.)</p>
<p>For my demo, here is the Finder method and filter descriptor for the Departments entity:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image20.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb20.png" border="0" alt="image" width="524" height="130" /></a><br />
<strong>Figure 15: Finder method for Departments entity</strong></p>
<p>In the SQL select query, you can see that I am selecting the DepartmentID, DepartmentName and Manager columns based on a certain department name.  The next step is to change the default mapping for the Managers property.  Here is how I have changed it:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image21.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb21.png" border="0" alt="image" width="344" height="97" /></a><br />
<strong>Figure 16: New mapping for Managers profile property</strong></p>
<p>For the Data source field to map, I have pointed this to the Manager column.  Other column choices are the other columns returned from the Finder method.  For the last text box (Manager field string format in AD), you can leave this unchanged.</p>
<p>That’s it.  Run another import, and you should now have your manager property coming from your external HR system.  For this to work, you will need to ensure your Department property is populated for your user profiles.  In my case, this value was still coming from AD.  That’s right, you can use a value that is imported from AD and pass that as a parameter to your BDC connection.  Pretty cool.</p>
<p>Let me make one last point on 1:Many import connections:  Be careful if your Finder method returns more than one record, and your mapped property does not allow multi-values.  For example, perhaps the HR system had two department records with the same name.  And for each record, a different manager is set.  When the import runs and it tries to pull the manager based on the name, two records will be returned. When this happens, the import process will take the first record it finds, and this may not be the one you want.  If you are using a multi-valued property, however, it works nicely and will store the values for all records that are found.</p>
<h4>Troubleshooting Tips</h4>
<p>When troubleshooting import problems, you’ll definitely want to go to the SharePoint logs (by default C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\LOGS).</p>
<p>When mapping, a profile property can be mapped to only one source (primary or secondary).  Similarly, a column from the Specific Finder (1:1 connection) or Finder (1:many connection), can only be mapped once.  For example, if you map the HireDate column to one profile property, you cannot also map it to another.</p>
<p>Remember that you can only map compatible data types.  Fortunately, you will get this error when you try to save your profile property.</p>
<p>When mapping strings, be careful about the column length.  If your profile property only supports 25 characters, and you try to store 50 characters that is the returned value from BDC, you will get an import error for that profile. You would only know this is a problem by seeing this error in the SharePoint logs.  (Note: you cannot change the length of any of the out-of-the-box profile properties.  In this case, you would need to create a new property.)</p>
<p>When creating BDC import connections using the UI, the entity selected from the catalog must expose both Finder and Specific Finder methods.  This is necessary, even if you plan on using only 1:1 or 1:Many connection types.</p>
<h4>Conclusion</h4>
<p>In this article, we covered everything you need to know about importing User Profiles from BDC.  And you now know as much about this as I do. <a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image25.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb25.png" border="0" alt="image" width="16" height="14" /></a></p>
<p>Coming up in Article 7, we will cover the BDC API.  This will allow you to call into the BDC programmatically from your custom applications, web parts, or any other .NET code you need to write.</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 5 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8#comments</comments>
		<pubDate>Tue, 03 Mar 2009 06:00:56 +0000</pubDate>
		<dc:creator>Wen He</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[Application Definition]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data]]></category>
		<category><![CDATA[Customization]]></category>
		<category><![CDATA[Enterprise Search]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[Search Center]]></category>
		<category><![CDATA[User Experience]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=2512</guid>
		<description><![CDATA[In this article, we will be focusing on BDC Search. Specifically we’ll be focusing on how to enable BDC Search, how to enable full and incremental crawls of BDC data sources, and how to create a search content source and search scopes. ]]></description>
			<content:encoded><![CDATA[<p><span>Welcome back to Part 5 of our 8 Business Data Catalog (BDC) series. In this article, we will be focusing on BDC Search. </span><span>Specifically we’ll be focusing on how to enable BDC Search, how to enable full and incremental crawls of BDC data sources, and </span><span>how to create a search content source and search scopes. We’ll then walk you through how to make our customer </span><span>data searchable and how to make the search results &#8220;actionable&#8221;.</span></p>
<p><span>If you’ve been following our BDC series, we’ve previously gone through the following topics:</span></p>
<ol>
<li><span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8">Part 1</a></span></span></span>, BDC Technical Architecture</span></li>
<li><span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8">Part 2</a></span></span></span>, Application Definition File (ADF) and its Development</span></li>
<li><span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8">Part 3</a></span></span></span>, Developing an ADF to Connect to Web Services</span></li>
<li><span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8">Part 4</a></span></span></span>, Using BDC Web Parts to Consume BDC Data</span> and Embedding BDC Data in Lists</li>
</ol>
<div><span>Now consider the following scenarios:</span></div>
<ul>
<li>How can I find the customer information for Great Lake Good Market in CRM?</li>
<li>How can I find the projects and resources details in Project Server 2007?</li>
<li>How can I find an employee&#8217;s legal name in HR system?</li>
</ul>
<p>With the help of the BDC Search, these all become possible. The Enterprise Search in MOSS can gather, index, and offer full-text search on all business data (entity instances) from applications registered in the BDC. Not only does it enable us to find answers in MOSS, but also it allows us to do so without having to leave SharePoint to go to these systems individually.  It makes integrating search into existing line of business (LOB) applications like a CRM solution easier.</p>
<p>For example, if we register the <strong>Northwind</strong> sample database in the BDC, Enterprise Search can crawl it and return customer data in search results. In addition, the Enterprise Search feature’s extensibility enables us to create customized search experiences. We can create a custom search tab in the Search Center where our users can search for customers in the database, and we can also create a custom UI for the search results based on which we can also take action.  So let&#8217;s dive right into it.</p>
<h3>BDC Search Overview</h3>
<p>As we&#8217;ve covered in prior articles, surfacing the BDC data to SharePoint using BDC Web Parts and lists is just first part of the BDC saga, it can also enable you to index and search on the BDC data. The following figure is an example of searching for information about a customer and then displaying both structured data from the database and unstructured documents and content stored within SharePoint.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image23.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb23.png" border="0" alt="image" width="644" height="370" /></a><br />
<strong>Figure 1:  Enterprise Search with BDC</strong></p>
<p>Here&#8217;s another example of leveraging BDC to index Project Server data and enable us to search the different objects (projects, tasks, resources, custom fields, lookup tables, and so on).  This is of great value because out of the box the Project Server data is not indexed. Only the objects in project workspace are indexed such as Issues, Risks, Documents, etc. For instance, if we are looking for project detail information for the Enterprise resource planning (ERP) project, we can search our Project Server and find the answers as shown in <strong>Figure 2</strong>:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image22.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb22.png" border="0" alt="image" width="644" height="402" /></a><br />
<strong>Figure 2: Search Project Server with BDC</strong></p>
<p>The BDC is truly a catalog of business applications that helps bridge the gap between MOSS and business applications by bringing in key data from various applications to SharePoint sites, lists, searches, and user profiles.  Let&#8217;s revisit the BDC architecture from <span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8">Part 1</a></span></span></span></span> with <strong>both XML</strong> <strong>Metadata</strong> and <strong>Search</strong> components highlighted in <strong>Figure 3</strong>.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image87.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb86.png" border="0" alt="image" width="644" height="450" /></a><br />
<strong>Figure 3:  BDC architecture with emphasis on the Search</strong></p>
<p>Firstly, we&#8217;ve highlighted the XML Metadata because it is the key element in the Application Definition that makes the BDC Search possible. BDC operates off of an XML-based Application Definition File (ADF). The metadata in ADF enables MOSS to crawl the BDC data source and add them to the search index.</p>
<p>Secondly, we highlight the Search component because the search engine uses a protocol handler to crawl and a security trimmer to filter results. BDC uses these just like third party implementations when supporting BDC searching.</p>
<p>BDC Search enables us to quickly find content in business data through search queries. It also integrates with search scopes and search center to become an integral part of MOSS Enterprise Search. Here I&#8217;ve created a custom search tab and a search scope for the BDC data to create a unique search experience in which the BDC search results are segregated from the rest of SharePoint search results. See <strong>Figure 4</strong>.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image88.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb87.png" border="0" alt="image" width="644" height="454" /></a><br />
<strong>Figure 4: Customized BDC Search Experience in Search Center</strong></p>
<p>By enabling the search of BDC data, BDC Search extends the SharePoint search capabilities. This extends the reach of the back-end LOB systems.  Today most LOB systems don’t have Full-Text search capability and BDC Search can serve for that purpose.</p>
<p>However, out of the box the BDC Search does not support indexing unstructured data like documents in a document management system. This is because the protocol handler for BDC is meant to connect to external structured data only. With custom protocol handlers, it&#8217;s possible to make MOSS index unstructured data . For example, using Web services to directly support BDC we can enable SharePoint to search, list, and retrieve documents from an external document management system via Web services.</p>
<p>Now let&#8217;s look into how to enable BDC Search.</p>
<h3>Enabling BDC Search</h3>
<p>One might think once we import an ADF, we can start to search.  BDC Search doesn&#8217;t come automatically, and we must enable it.  To enable BDC Search, we must first make sure these two methods exist in the ADF for the entity you want to crawl:</p>
<ol>
<li>SpecificFinder</li>
<li>IdEnumerator</li>
</ol>
<p>These are the only required metadata for Enterprise Search to use BDC to index the business application&#8217;s data.</p>
<p>In <span><span><span><span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8">Part 2</a></span></span></span>,</span> we’ve covered the ADF and its vocabulary: System (data source), Entity (table), Method (operation on entity), and Association (relationship). There are three primary types of methods: Finder, SpecificFinder and IdEnumerator. An IdEnumerator method returns a searchable list of unique IDs for an entity. This list enables indexing of the entities and SpecificFinder is then used to find details for the entity instance based on the specific ID. Therefore, IdEnumerator and SpecificFinder work together to enable Enterprise Search to use BDC to crawl the business data.</p>
<p>Now since we have a good understanding of what it takes, let&#8217;s put it in action. We&#8217;re going to use <a href="http://msdn.microsoft.com/en-us/library/bb736296.aspx"><strong>Business Data Catalog Definition Editor</strong></a>, a free tool from the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=6D94E307-67D9-41AC-B2D6-0074D6286FA9&amp;displaylang=en"><strong>MOSS SDK</strong></a>, to create our ADF (shown in <strong>Figure 5</strong> below). Though one of the limitations of this tool is that it doesn&#8217;t create a <strong>Finder</strong> method, BDC Search doesn&#8217;t need use this anyway, so it works very well for creating an ADF that&#8217;s just used for searching. You can learn how to use this tool <a href="http://msdn.microsoft.com/en-us/library/bb736296.aspx">here</a>.</p>
<p><span><span><span><span><span><span><span><span><span>Incidentally, both <a href="http://www.simego.net/MOSS_BDC_Design_Studio.aspx">MOSS BDC Design Studio</a> and <a href="http://www.lightningtools.com/bdc-meta-man/default.aspx">BDCMetaMan</a> will create these methods necessary to implement BDC searching.</span></span></span></span></span></span></span></span></span></p>
<p>We begin by adding a LOB system for our sample database, a modified version of <strong>Northwind</strong> database. We&#8217;re going to use the <strong>Customers</strong> entity that resembles one in a CRM system (or the like).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image89.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb88.png" border="0" alt="image" width="644" height="380" /></a><br />
<strong>Figure 5: </strong><strong>Create Application Definition</strong></p>
<p>To index and search for Customers entity in the database, we&#8217;re performing the following tasks:</p>
<ol>
<li>Define an IdEnumerator method in the BDC definition (<strong>Figure 6</strong>)</li>
<li>Define a SpecificFinder method in the BDC definition (<strong>Figure 7</strong>)</li>
</ol>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image90.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb89.png" border="0" alt="image" width="644" height="138" /></a><br />
<strong>Figure 6: Define a special type of MethodInstance method IdEnumerator</strong>.</p>
<p>The <strong>IdEnumerator </strong>method returns a list of CustomerID records, which will be indexed by MOSS Search. So now we know that the sole purpose of <strong>IdEnumerator </strong>here is to enable Search.  Here&#8217;s the SQL query:</p>
<div><span style="Courier New;">Select CustomerID from Customers</span></div>
<div><span><br />
</span></div>
<div><span> <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image91.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb90.png" border="0" alt="image" width="644" height="218" /></a><br />
</span><strong>Figure 7: Define a SpecificFinder</strong></div>
<div>
<p>The <strong>SpecificFinder</strong> method then uses the CustomerID returned from above IdEnumerator method as a parameter (<strong><span class="kwrd">where</span> CustomerID=@CustomerID</strong>) to retrieve the fields for this particular customer. This is how the BDC search is able to search the entire Customers entity. So to make a field searchable, we just include it in the query and return as type <strong>string</strong>.  Here&#8217;s the SQL Query:</p>
<p><span style="x-small;">Select CustomerID,CompanyName,ContactName,ContactTitle,Address,City,Region,PostalCode,Country,Phone,Fax<br />
</span><span style="x-small;">from Customers<br />
</span><span style="x-small;">where customerID=@CustomerID</span></p>
<h3>Import Application Definition</h3>
<p>Now we have our required metadata well-defined in the ADF, we are ready to export the XML metadata to an ADF file and then import it to MOSS.  Once we have it imported, we can confirm that our Customers entity implements the two methods in SSP Administration page by viewing application and then entity. The Crawlable property under Entity Information means our Customers entity is available to be crawled, as shown in <strong>Figure 8</strong>.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image92.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb91.png" border="0" alt="image" width="644" height="209" /></a><br />
<strong>Figure 8: View Entity Information in SSP</strong></p>
<p>So far we have started from creating the ADF to importing it to enable searching. Since we can enable searching on any entity that has an IdEnumerator and SpecificFinder defined, we don&#8217;t have to start from scratch to set this up specifically for search.  We can just go straight to configuring the Enterprise Search.</p>
<h3>Configuring the Enterprise Search</h3>
<p>Configuring the Enterprise Search consists of the following steps:</p>
<ol>
<li>Create a content source</li>
<li>Perform a full crawl</li>
<li>Create a search scope (optional)</li>
<li>Add scope rule (optional)</li>
</ol>
<p>We start by creating a content source for our BDC application and performing a full crawl, then optionally create a search scope and scope rule.  These steps are very straight forward so I will focus on the main points. If you&#8217;re interested in each and every detail, check out the <a href="http://sharepointmagazine.net/technical/customisation/customizing-search-series-new-content-and-scope-from-a-bdc-application">Customizing Search Series</a> by Steve Mann.</p>
<p><strong>Step 1: Create a content source (Figure 9)</strong></p>
<p>In order to create a content source, go to SSP Administration page –&gt; Search Settings under Search section, and click on &#8220;Content Sources and Crawl Schedules&#8221;. Click on &#8220;New Content Source&#8221; and give a name for this content source; specify &#8220;Business Data&#8221; as the type of the content to be crawled. Additionally, if we wish to index the content at regular intervals we could create a Crawl schedule that defines our full crawl schedules. Here is how my screen looks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image93.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb92.png" border="0" alt="image" width="308" height="484" /></a><br />
<strong>Figure 9: Create a content source</strong></p>
<p><strong>Step 2: Perform a full crawl (Figure 10)</strong></p>
<p>In the above step, since I&#8217;ve checked the Start full crawl of this content source, it will initiate a full crawl of the new content source, and we should now see the content source crawling as shown below:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image94.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb93.png" border="0" alt="image" width="563" height="197" /></a><br />
<strong>Figure 10: Perform a full crawl</strong></p>
<p>We can also check the crawl log to make sure that the BDC data has been indexed correctly. At this point, we should be able to search our customers table. If we search for &#8220;great lakes&#8221;, we get search results as shown in <strong>Figure 1 </strong>above.</p>
<p>As we can see, both documents and BDC Search Results are listed together. This demonstrates some of the real power behind Enterprise Search. That is, we’re seeing SharePoint content side by side with external BDC content. This is great especially when we intend to search everything including both documents and BDC sources.</p>
<p>Another real power of Enterprise Search is its extensibility. We can create customized search experiences by creating a custom search tab in the Search Center where our users can search for customers in the database, and we can create a custom UI for the search results. This is what we’re going to do to separate the BDC Search results from other content. We can achieve this by performing the following two additional steps: 1) creating a search scope for BDC and 2) adding a scope rule.</p>
<p><strong>Step 3: Create a search scope (Figure 11)</strong></p>
<p>In order to create a search scope, go to the SSP Administration page, under Search section, click on Search settings. In the &#8220;Scopes&#8221; area, click on &#8220;View Scopes&#8221;.  Click on &#8220;New Scope&#8221;, give it a name.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image95.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb94.png" border="0" alt="image" width="644" height="302" /></a><br />
<strong>Figure 11: Create a search scope</strong></p>
<p><strong>Step 4: Add scope rule </strong></p>
<p>Click on &#8220;Add Rules&#8221; where it says &#8220;Empty &#8211; Add Rules&#8221; on the newly added scope (<strong>Figure 12</strong>).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image96.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb95.png" border="0" alt="image" width="644" height="276" /></a><br />
<strong>Figure 12: Add scope rule</strong></p>
<p>Specify a Content Source as shown below (<strong>Figure 13</strong>):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image97.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb96.png" border="0" alt="image" width="644" height="233" /></a><br />
<strong>Figure 13: Add scope rule &#8211; specifying a content source</strong></p>
<p>Our BDC Search scope has been created and is now available in the search drop-down as shown in <strong>Figure 14</strong>. If we now search for &#8220;great lakes&#8221;, we get search results back from the existing database as shown in <strong>Figure 4 </strong>above.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image98.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb97.png" border="0" alt="image" width="644" height="137" /></a><br />
<strong>Figure 14: BDC Search scope is available for use</strong></p>
<p>As you have seen, the last two steps, even though optional, do give us additional value.  That is, to segregate the BDC search results from the rest of SharePoint search results so that we can focus on just business data. Thus better search relevance is accomplished through the extensibility!</p>
<h3>BDC Search Access Permission</h3>
<p>It is a good time for us to know how to configure BDC Search access permission so that it will work out-of-the-gate. Often times we forget about it or ignore it, and only when the crawling fails or when the search returns no results, do we go in and dig the logs, even though it is not a bad troubleshooting methodology.</p>
<p>In these examples, we’ve been using &#8220;PassThrough&#8221; authentication in the ADF. That means additional settings have to be configured so that the &#8220;Default Content Access Account&#8221; (the account used to crawl) has access to the database. Also the “Default Content Access Account” must have appropriate rights to the BDC application and entity.</p>
<p>We’ll achieve that in the following steps:</p>
<ol>
<li>Create a new Active Directory account for BDC search. We’ll call ours MOSS.Search.</li>
<li>Change the default content access account to that account in search settings (<strong>Figure 15</strong>).</li>
<li>Change search crawler account to that account under Operations –&gt; Services –&gt; Office SharePoint Server Search.</li>
<li>Grant this account db_datareader access to the database in SQL Server.</li>
<li>Grant this account Execute, Selectable in clients in Manage permissions for the ADF (<strong>Figure 16</strong>).</li>
</ol>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image100.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb99.png" border="0" alt="image" width="644" height="344" /></a><br />
<strong>Figure 15:  Specify the Default Content Access Account</strong></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image101.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb100.png" border="0" alt="image" width="644" height="208" /></a><br />
<strong>Figure 16:  Grant Execute, Selectable permissions</strong></p>
<p><strong>Note:</strong> there might be a delay of a few minutes after the permission is changed on BDC application. You may delete and re-import the BDC application definition at when needed &#8212; no need to re-crawl as long as the BDC name is not changed.</p>
<h3>Enabling Incremental Crawling</h3>
<p>Next, we’re going to show you how create an enhancement to our ADF to support incremental crawling through the use of the __BdcLastModifiedTimestamp entity property.</p>
<p>To optimize search performance, it’s important to have incremental crawl. As you may know, Incremental Crawl is a process of crawling only new or changed content from the previous full or incremental crawl. This means that we have to let BDC know what has changed since its last crawl.</p>
<p>To ensure that incremental crawls can be performed in the database when indexing, we’ll need to enhance the IdEnumerator method that has a return field that represents the last update time for that particular row. The Type attribute of the __BdcLastModifiedTimestamp property must be System.String and its value must be set to the value of the Name attribute of the TypeDescriptor for the field returned by the IDEnumerator method that contains the last modified date and time of the entity instance. This is illustrated below.</p>
<p>In our Customers table, we start by adding a column called LastUpdated of data type DateTime to indicate the last modified time of a single row. SharePoint indexing service will use that as a time stamp and incremental crawling is enabled. SQL-knowledgeable people should not confuse this with a timestamp data type. The example we are walking through is specific to SQL Server, but the concept will apply to other databases or Web Service methods.</p>
<p>Here are the specific steps to enable incremental crawling:</p>
<ol>
<li>Update the database table to add a LastUpdated column of datetime data type (<strong>Figure 16</strong>).</li>
<li>Ensure the value of LastUpdated column is set to the current date and time when the row changes. (This can be accomplished with an Update trigger.)</li>
<li>Update ADF to have the __BdcLastModifiedTimestamp property of the entity set to LastUpdated (<strong>Figure 17).</strong></li>
<li>Update ADF to have IdEnumerator mothod return LastUpdated field (<strong>Figure 18</strong>).</li>
<li>Update ADF to have a TypeDescriptor with its TypeName attribute set to System.DateTime (<strong>Figure 19</strong>).</li>
</ol>
<p>The following figures are the screens for performing the above tasks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb.png" border="0" alt="image" width="228" height="244" /></a><br />
<strong>Figure 16: Create a LastUpdated column of datetime type in SQL Server</strong></p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image102.png" alt="" /><br />
<strong>Figure 17: Add the __BdcLastModifiedTimestamp property</strong></p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image103.png" alt="" /><br />
<strong>Figure 18: Have IdEnumerator method return LastUpdated field</strong></p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image104.png" alt="" /><br />
<strong>Figure 19: Add a TypeDescriptor with its TypeName attribute set to System.DateTime</strong></p>
<p>To compare the performance, I then performed an incremental crawl.  This is shown in <strong>Figure 20</strong> below.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image105.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb104.png" border="0" alt="image" width="644" height="249" /></a><br />
<strong>Figure 20: Comparison between the incremental crawling and the full crawling.</strong></p>
<p>In our sample, it took significantly less time in the incremental crawling than the full crawl (35 seconds vs. 54 seconds).  Depending on the size of the database and the number of changes that need to be processed with each crawl, the difference in crawl times will vary. The key of enabling incremental crawl here is performance so that the back-end systems are not unnecessarily burdened by the crawling.</p>
<h3>Actions</h3>
<p>Lastly, let’s show you how we can make our BDC search results &#8220;actionable&#8221; by creating a custom action on the Customers entity. There are two ways to create a custom action. It can be defined either in the ADF or added after the ADF is imported by going to SSP administration page (View Application –&gt; View Entity).</p>
<p>By default through the <strong>SpecificFinder</strong> method, we get a default view Profile action that links to a simple page with your search results. This is where the customization comes in, and you could create custom Web Parts to provide more user-friendly and richer user experience. We’ll dedicate Part 8 of this series to Custom Actions so you have the best for last. For this article, let&#8217;s quickly create a custom action to map the customer using Live Search Maps (maps.Live.com).</p>
<p>Here are the specific steps to enable custom action with Live Search Maps:</p>
<ol>
<li>Add Action and set parameters (<strong>Figure 21)</strong></li>
<li>Check action<strong> (Figure 22</strong>)</li>
</ol>
<p>Go to SSP administration page (View Application –&gt; View Entity), add action and configure URL parameters.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image106.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb105.png" border="0" alt="image" width="518" height="484" /></a><br />
<strong>Figure 21:  Create a custom action in SSP</strong></p>
<p>The parameter &#8220;Address&#8221; will be substituted at index &#8220;0&#8243;, which is specified as a querystring URL to maps.live.com. If you have already deployed your ADF before creating a custom action, you will need to redeploy it if you use this approach to adding a custom action.</p>
<p>Check the custom action to ensure it&#8217;s configured and ready for use <strong>(Figure 22</strong>).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image107.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb106.png" border="0" alt="image" width="644" height="125" /></a><br />
<strong>Figure 22: Live Map Action appears under Actions</strong></p>
<p>Now let&#8217;s test-drive our search and custom action in the following two steps:</p>
<ol>
<li>Search any customer in the Search Center (<strong>Figure 23</strong>)</li>
<li>Perform the custom action based on the search result (<strong>Figure 24</strong>)</li>
</ol>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2009/01/image2.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2009/01/image-thumb2.png" border="0" alt="image" width="644" height="217" /></a><br />
<strong>Figure 23: Search result of a customer entity</strong></p>
<p>Clicking on &#8220;The Big Cheese<strong>&#8220;</strong> will take us to the default profile page, where we can see and act upon the custom action <strong>Live Map (maps.live.com)</strong> as shown below. Clicking on <strong>Live Map</strong> will issue a search on maps.live.com using the address of &#8220;The Big Cheese&#8221;. Here&#8217;s the live map (<strong>Figure 26</strong>). Neat!</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image108.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb107.png" border="0" alt="image" width="240" height="322" /></a><br />
<strong>Figure 24: BDC Search Results with Live Map action available</strong></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image109.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb108.png" border="0" alt="image" width="644" height="439" /></a><br />
<strong>Figure 25:  Live Map of the searched customer</strong></p>
<h3>Conclusion</h3>
<p><span style="x-small;">In this article we have covered the concepts behind BDC search and how to enable it. We&#8217;ve then walked you through how to make our Customer data searchable, and how to make a custom action on search results. In doing so, we&#8217;ve demonstrated the power behind BDC and MOSS Enterprise Search. Even though we have only used a database in our example, this is also all possible with Web Services, provided the SpecificFinder and IdEnumerator methods are still in place. Hope you have enjoyed reading it as much as I have enjoyed writing it. Look forward to your comments and suggestions.  Aloha!</span></div>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-5-of-8/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 4 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8#comments</comments>
		<pubDate>Sun, 11 Jan 2009 06:58:29 +0000</pubDate>
		<dc:creator>Randy Williams</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[MOSS]]></category>
		<category><![CDATA[sharepoint]]></category>
		<category><![CDATA[web parts]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=2188</guid>
		<description><![CDATA[In this Part 4, which is much less technical, the focus is two primary ways to consume BDC data through the UI.  This will include Business Data Web Parts and incorporating Business Data into SharePoint lists.]]></description>
			<content:encoded><![CDATA[<p><span style="x-small;">Welcome back.  We are now on Part 4 of our Business Data Catalog (BDC) series.  If you are just joining us, here is what’s already been covered:</span></p>
<p><span style="x-small;">In </span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8" target="_blank"><span style="x-small;">Part 1</span></a><span style="x-small;">, I covered the purpose and technical architecture of the BDC.  A quick look at the BDC in action was also introduced.</span></p>
<p><span style="x-small;">In </span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8" target="_blank"><span style="x-small;">Part 2</span></a><span style="x-small;">, I covered the Application Definition File (ADF) in depth and how to develop one to connect to a back-end database.</span></p>
<p><span style="x-small;">In </span><a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8" target="_blank"><span style="x-small;">Part 3</span></a><span style="x-small;">, I continued the discussion of the ADF, but looked at how to develop an ADF to connect to Web Services. </span></p>
<p><span style="x-small;">In this Part 4, which is much less technical, the focus is two primary ways to consume BDC data through the UI.  This will include Business Data Web Parts and incorporating Business Data into SharePoint lists.</span></p>
<h4><strong>Business Data Web Parts</strong></h4>
<p><span style="x-small;">Business Data Web Parts are the most common way to surface BDC data to end-users.  Using them, users can filter and sort the data to quickly find the content needed.  Their flexibility and ease of use empowers users to perform many tasks that would otherwise require custom development.  In MOSS Enterprise edition, there are five Web Parts and we will cover each in this article:  Business Data List, Business Data Item, Business Data Related List, Business Data Actions, and Business Data Item Builder.  Each of these Web Parts will only provide a read-only view of the external data, so don’t plan on making any changes through them.  There are ways of updating the external data, but we will wait until Part 8 to get into this.</span></p>
<h5><strong>Business Data List Overview</strong></h5>
<p><span style="x-small;">The Business Data List is the most powerful and most commonly used Business Data Web Part.  At its heart, it is a Data View Web Part and is used to display a sheet of columns and rows (or items).  The items displayed are based on filter criteria that the user enters.  Here is a simple example where we find all customers located in the WA (Washington) Region.</span></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image1.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb1.png" border="0" alt="image" width="624" height="231" /></a><br />
<span style="x-small;">Figure 1: Business Data List Web Part</span></p>
<p>These customers that you see are defined in a SQL Database, and the information is pulled in real time.  This is a powerful way to expose your line-of-business data within a centralized SharePoint interface.</p>
<p>Let’s quickly walk through how I got here.  As with any Web Part, you start off by editing a Web Page (Figure 2) and adding a Web Part into one of the Web Part zones (Figure 3).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image61.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image6-thumb.png" border="0" alt="image" width="244" height="146" /></a><br />
Figure 2: Editing the Page from the Site Actions Menu</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image3.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb3.png" border="0" alt="image" width="644" height="69" /></a><br />
Figure 3: Adding a Web Part to a Zone</p>
<p>After clicking Add a Web Part, you will be presented with all the Web Parts that are available for that site collection.  In the Business Data category, you should see the five Business Data Web Parts.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image4.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb4.png" border="0" alt="image" width="604" height="250" /></a><br />
Figure 4: Business Data Web Parts</p>
<p>After you select the Business Data List Web Part and click the Add button, you will be presented with this next screen, prompting you to now configure the Web Part.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image5.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb5.png" border="0" alt="image" width="644" height="101" /></a><br />
Figure 5: Default display after adding a Business Data List Web Part to a zone</p>
<p>After you click the Open the tool pane link, you are presented with all the configuration properties for the Business Data List Web Part.  The required setting is that you must select the Type from the catalog as shown here.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image6.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb6.png" border="0" alt="image" width="244" height="101" /></a><br />
Figure 6: Specifying the type</p>
<p>The Type refers to the entity in one of the ADFs that have been loaded.  The entity must also have a finder method defined.  You can either enter in the name directly and click the Check Types icon <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image7.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb7.png" border="0" alt="image" width="16" height="15" /></a> .  Or, you can select the Browse <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image8.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb8.png" border="0" alt="image" width="16" height="12" /></a> icon to see what is available.  (Security Note: Only those applications and types that you have Select in Clients and Execute permission on will be shown.)  In the image shown below, one of the four types can be selected.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image9.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb9.png" border="0" alt="image" width="334" height="190" /></a><br />
Figure 7: Browsing applications and types stored in the catalog</p>
<p>In the first screen shot above (Figure 1), you saw a list of customers.  To get this, I selected the Customers type from SynergyData (the name of the BDC Application).  Initially, this will return all of the columns that are defined in the Finder method within the ADF as shown below.  (Note: I also exited Edit Mode to return to the regular view).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image10.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb10.png" border="0" alt="image" width="644" height="127" /></a><br />
Figure 8: Business Data List Ready for Action</p>
<p>At this point, the Web Part is ready for filtering and sorting operations.  To filter, you first choose one of the Filter choices from the drop down list shown on the top left as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image11.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb11.png" border="0" alt="image" width="185" height="103" /></a><br />
Figure 9</p>
<p>What is shown are the filter options that are defined by the FilterDescriptors as covered in <a href="http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8" target="_blank">Part 2</a>.  Here is what is defined for this Customers entity in the ADF:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image12.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb12.png" border="0" alt="image" width="404" height="66" /></a><br />
Figure 10</p>
<p>If the type of filter is a Wildcard, you will have several filter options that you can select in the second drop down list as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image13.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb13.png" border="0" alt="image" width="177" height="77" /></a><br />
Figure 11</p>
<p>If you’ve specified Comparison, you only have one choice:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image14.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb14.png" border="0" alt="image" width="180" height="52" /></a><br />
Figure 12</p>
<p>You can add additional criteria by clicking the Add button and adding another filter.  These are all processed as an “And” operation, meaning that only items that match all criteria are shown.  To sort, as with any SharePoint view, you simply click on any of the columns headings.</p>
<p>You can also filter by using the column headings.  In this example, I start off by searching for all customers in the SP region.  This initially returns six items.  I then filtered the display to only show those in Sao Paulo.  The advantage is that you can still perform some filter operations even though the column is not defined as a filter descriptor.  Here is the result:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image15.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb15.png" border="0" alt="image" width="624" height="255" /></a><br />
Figure 13: Column Filtering on City</p>
<p>What if you wanted to just filter columns?  For example, perhaps you only need to show a handful of columns for each customer.  This is easy and is done by editing the default view for the Web Part.  To do this, you can go back into edit mode for the page and click the Edit View link as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image16.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb16.png" border="0" alt="image" width="644" height="171" /></a><br />
Figure 14: Editing Business Data List View</p>
<p>This will then take you to a screen where you can adjust the view in a number of ways.  One of the choices is to select the columns as their position.  As you can see below, this works just like a regular view for a SharePoint list.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image17.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb17.png" border="0" alt="image" width="304" height="214" /></a><br />
Figure 15: Selecting columns to display</p>
<p>From this same screen, you also have some other useful features.  For example, you can “hard code” a specific filter so that only certain items display.  For example, perhaps each region has its own SharePoint page, and on that page, you only want to display the customers in that region.  You could configure the settings as shown here and prevent the user from changing the filter:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image18.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb18.png" border="0" alt="image" width="244" height="179" /></a><br />
Figure 16: Only show customers in the SP Region</p>
<p>Here is the result:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image19.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb19.png" border="0" alt="image" width="624" height="275" /></a><br />
Figure 17: Customers in the SP Region (and user cannot change the filter)</p>
<p>While editing the view, you have many more options such as the default sort and additional filter options.  I&#8217;ll leave these to your own study.</p>
<h5><strong>Business Data List Advanced Settings</strong></h5>
<p>Let&#8217;s turn our attention to more advanced capabilities.  Since the Business Data List Web Part is a type of Data View Web Part, you have a number of settings such as customizing the XSL or Parameters.</p>
<p>The XSL (<a href="http://en.wikipedia.org/wiki/Xslt" target="_blank">eXtensible Stylesheet Language</a>) is an XML-based transformation language that converts XML that is returned from BDC into HTML that is displayed for the Web Part.  This XSL is generated automatically when you select a catalog type such as customers.  While you can edit this XSL directly inside a dialog box for the Web Part, it is much easier to copy and paste this into a file and edit within Visual Studio, SharePoint Designer or your favorite XSL editor.  Keep in mind that the XSL contains not only the HTML results, it also contains the HTML for the selection criteria, the Actions toolbar, and the column headers.</p>
<p>A simple XSL change would be to enable alternating line styles.  The result looks like this:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image20.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb20.png" border="0" alt="image" width="624" height="329" /></a><br />
Figure 18: Modified XSL to highlight alternating items</p>
<p>To enable this, I simply inserted the &lt;xsl:if&gt; condition you see here highlighted in this code snippet:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image33.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb33.png" border="0" alt="image" width="576" height="140" /></a><br />
Figure 19: XSL</p>
<p>When defining the XSL, you can either link to an XSL stylesheet (located within a document library) or define the XSL for this specific Web Part instance.  Linking the XSL would be best for identical Web Parts that you have in different locations.  Since the XSL is generated for the specific columns, a shared XSL file cannot be used different Business Data Lists with different types (entities).  Having a linked XSL sheet is also helpful to ensure that changes made to the Web Part will not erase your custom XSL code.</p>
<p>For those not too comfortable with XSL, you have some control over the Web Part using SharePoint Designer (SPD).  Like the changes to the view we saw above, SPD also allows you to define filtering and sorting behavior.  One advantage with it, however, is that you can define filters based on variables such as the <a href="http://en.wikipedia.org/wiki/Querystring" target="_blank">query string</a>.</p>
<p>To help explain, let&#8217;s adapt the Region example we just covered in Figure 17 above where we hard coded the filter for the SP Region.  In this case, let&#8217;s pull that Region from the query string instead which would give us a more flexible design.</p>
<p>This section assumes you have a basic understanding of editing pages in SPD.  For a brief overview, see my friend Ishai Sagi&#8217;s introduction <a href="http://www.sharepoint-tips.com/2007/04/sharepoint-designer-article-1-how-to.html" target="_blank">here</a>.  Once in SPD, open up the page for the web site where the Web Part lives.  We click on the Web Part and access the Common Data View Tasks by clicking on the tiny icon as highlighted here in red:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image21.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb21.png" border="0" alt="image" width="664" height="268" /></a><br />
Figure 20: Customizing Web Part in SPD</p>
<p>Once you click the icon, it will expand the Common Data View Tasks dialog as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image22.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb22.png" border="0" alt="image" width="233" height="244" /></a><br />
Figure 21: Common Data View Tasks Dialog</p>
<p>From this point, click the Parameters link.  Click the New Parameter button and fill in the contents as shown below.  This will create a new parameter named Region that will be pulled from the query string.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image23.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb23.png" border="0" alt="image" width="404" height="269" /></a><br />
Figure 22: Adding a New Parameter</p>
<p>Now that the Region parameter is created, we can create the filter that is based on its value.  Return to the main Common Data View Tasks dialog and this time select Filter.  Create a new filter by as you see here.  Note: The [Region] value is the parameter that you just created.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image24.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb24.png" border="0" alt="image" width="354" height="210" /></a><br />
Figure 23: Adding a New Filter Based on the Parameter</p>
<p>Save all of your work in SPD and refresh the page in the browser.  If you do nothing else, you&#8217;ll find that your Business Data View Web Part does not return any items.  This is because the Web Part is expecting a Region query string value.  Edit the URL in the address bar, and add the query string and value after your page.  For example:</p>
<p>http://WebApp/teamsite/default.aspx?Region=SP</p>
<p>Now run a new query using the Web Part.  You should find that all the item results are automatically filtered to only the SP region.  If you prefer, you can supply a default value for the parameter when you create it as shown in Figure 22 above.</p>
<p><strong>Important Note</strong>: When editing the Web Part using SPD, it will change the current XSL and Parameter settings.  So, be careful if you will be customizing the XSL manually and also through SPD as it will overwrite your changes.</p>
<h5><strong>Business Data Item Web Part</strong></h5>
<p>Now that we have thoroughly covered the Business Data List Web Part, the remaining Web Parts are much easier to learn.  The next one on our list is the Business Data Item.  This Web Part is intended to just show you the column values for a single item that is returned from BDC.  It is often used in conjunction when you connect Web Parts as you&#8217;ll see shortly.  Before we go there, let&#8217;s first look at a simple example.</p>
<p>Here you see the contents of one customer:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image25.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb25.png" border="0" alt="image" width="254" height="217" /></a><br />
Figure 24: Business Data Item Web Part</p>
<p>To configure the Business Data Item Web Part, first set the Type from the catalog picker.  Then specify the item by searching for it.  Here is how it the configuration looks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image26.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb26.png" border="0" alt="image" width="243" height="207" /></a><br />
Figure 25: Configuring the Business Data Item</p>
<p>While this is easy to do, it&#8217;s not too practical to hard code in a single item.  Instead, let&#8217;s see how you can connect this to our Business Data List Web Part.  This will allow you to select a customer from the list and then display the customer&#8217;s details.  To start, add a Business Data List and Business Data Item Web Part on the same page.  They can be in different zones but must be on the same page.  You must also make sure they are both set to the same Type (such as Customers).  From here, you need to establish a Web Part connection between them. You can do it as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image27.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb27.png" border="0" alt="image" width="504" height="179" /></a><br />
Figure 26: Connecting Business Data List to Business Data Item</p>
<p>This will send the selected item from the Customers List (on the left) to the Customers Item (on the right).  Once these are connected, you get the display as shown below.  Notice that selecting The Cracker Box shows this customer in the Business Data Item Web Part on the right.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image28.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb28.png" border="0" alt="image" width="414" height="267" /></a><br />
Figure 27: Result of Web Part Connection</p>
<h5><strong>Business Data Related List Web Part</strong></h5>
<p>The Business Data Related List Web Part is used when you want to pull related items using an association defined in the ADF.  For example, perhaps we want pull the sick days a certain employee has taken.  Or we want to list the orders for a selected customer.  Let&#8217;s see how this latter example would work.  To start, let&#8217;s add a Business Data List and Business Data Related List Web Part to our page.  As we have been doing, we configure the Business Data List to use the Customer Type in the catalog.  We then point the Business Data Related List to the Orders Type.  Here&#8217;s how the Business Data Related List looks when configuring it:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image29.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb29.png" border="0" alt="image" width="244" height="229" /></a><br />
Figure 28: Configuring the Business Data Related List</p>
<p>Notice that you must specify the relationship on the Orders Type that you want to use.  This choice is provided to us since it was defined in the ADF as you can see here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image30.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb30.png" border="0" alt="image" width="524" height="88" /></a><br />
Figure 29: Association between Customers and Orders in the ADF</p>
<p>Now that the Web Parts are configured, we need to establish a connection between them.  Once that is done, we get the following result:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image31.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb31.png" border="0" alt="image" width="404" height="251" /></a><br />
Figure 30: Result of Connecting Business Data List and Business Data Related List</p>
<p>Of course, if you prefer, you can have the selected customer drive both the Orders List and the single customer in the Business Data Item.  Here&#8217;s how it would then look:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image32.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb32.png" border="0" alt="image" width="554" height="249" /></a><br />
Figure 31: Connecting Three Web Parts Together</p>
<h5><strong>Business Data Actions</strong></h5>
<p>Actions are a common way of displaying or editing a single item, and we will cover them in detail within Part 8.  To give you a basic overview, let&#8217;s look at a sample action that is defined in the ADF.  Here is one that is defined for our Customers entity:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image34.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb34.png" border="0" alt="image" width="554" height="101" /></a><br />
Figure 32: Action Defined for Customer Entity in ADF</p>
<p>Notice that the action has a name (in the figure above it is View Profile) and contains one or more ActionParameter elements.  This column (or columns) is often the Identifier for the entity.  This means it is used to uniquely identify this item.  For our customer&#8217;s entity, the CustomerID will be provided as a query string variable to a page called dbo.Customers.aspx.  How this is processed is covered in the Business Data Item Builder Web Part a bit later.</p>
<p>Now that you understand the basics of actions, the Business Data Actions Web Part simply lists all of the actions defined for a single item.  Here is how the configuration for the Web Part looks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image35.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb35.png" border="0" alt="image" width="182" height="244" /></a><br />
Figure 33: Configuring the Business Data Actions Web Part</p>
<p>Notice that you configure it much like the Business Data Item Web Part.  The only difference is you can specify which actions to display and how should they be displayed (i.e. the Style).  The Style options are Bulleted List, List, and Tool bar.  Once you have it configured (and connected to a Business Data List Web Part), here is how the results look with a Bulleted List:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image36.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb36.png" border="0" alt="image" width="484" height="124" /></a><br />
Figure 34: Connecting the Business Data List and Business Data Actions</p>
<p>When you click on the View Profile link, it takes you to the Url defined for this action which is http://spserver:22222/ssp/admin/Content/dbo.Customers.aspx?CustomerID=LAZYK.  Incidentally, you can also access these actions by clicking the View Profile context menu as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image49.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb49.png" border="0" alt="image" width="364" height="148" /></a><br />
Figure 35: Accessing the Actions from the Business Data List</p>
<p>As you can see, this is a flexible way of sending a single item to any web page, whether this is in SharePoint or an external web site.  We&#8217;ll look at other possibilities with Actions in Part 8.</p>
<h5><strong>Business Data Item Builder</strong></h5>
<p>The Business Data Item Builder is a special, invisible Web Part that is responsible for extracting the value from a query string variable and delivering it to a Business Data Item Web Part.  By invisible, I mean it is only visible in edit mode; when in normal operation, it is hidden.</p>
<p>When adding this Web Part to a page, there is no configuration on it other than connecting it to a Business Data Item Web Part.  The way it works is by extracting a variable from the query string (for example CustomerID) and sending it to the Business Data Item Web Part.  It knows what variable to extract by reading the ActionParameter defined in the ADF.</p>
<p>A good way of understanding how the Business Data Item Builder Web Part works is by looking at one of the profile pages.  A profile page, which I will cover in Part 8, is a page that typically displays a single item in some way.  Profile pages can be created automatically when you import the ADF.  For an automatically created profile page, this is comprised of a Business Data Item Builder and a Business Data Item Web Part.</p>
<p>To demonstrate, when clicking the View Profile link shown in Figure 35 above takes us to the auto-generated profile page as shown below.  Notice you only see one Business Data Item Web Part.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image39.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb39.png" border="0" alt="image" width="195" height="244" /></a><br />
Figure 36: Profile for a Single Customer</p>
<p>If we edit the page, however, you&#8217;ll notice the Business Data Item Builder.  This web part is automatically connected to the Business Data Item Web Part.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image40.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb40.png" border="0" alt="image" width="244" height="160" /></a><br />
Figure 37: Editing the Profile Page for Customers</p>
<p>That is the only purpose for the Business Data Item Builder, so you will probably not find yourself using it all that often.</p>
<p>With that, this wraps up our discussion on the out of the box Web Parts for the Business Data Catalog.  Let’s turn our attention to the second (and much shorter) half of this article.</p>
<h4><strong>Incorporating Business Data within Lists</strong></h4>
<p>While the Business Data Web Parts are useful, sometimes you just need to embed external data right within a SharePoint list or library.  For example, perhaps you already have a contact list in SharePoint for all your customers, and you are maintaining this separately from your <a href="http://en.wikipedia.org/wiki/Customer_relationship_management" target="_blank">CRM system</a>.  A better solution would be to add Business Data columns to your contact list and pull in some of this data from CRM.  This means you would only maintain the customer entry in CRM, and these changes are pulled into SharePoint.</p>
<p>Another advantage is that you can see information from multiple sources all merged together.  Let’s say that a list of the products your company sells is stored within a SharePoint picture library.  You can add a Business Data column to the library which can pull the current product name and inventory level from an external <a href="http://en.wikipedia.org/wiki/Enterprise_resource_planning" target="_blank">ERP</a> database.  Now you can see the product’s picture, the product name, and its inventory in one consolidated view.</p>
<p>When you add a Business Data column to a list, SharePoint will pull the data from the external system and store a cached copy of it in the list.  This is quite different from Web Parts where you are always pulling the real-time value from the external system.  The advantages of caching the data in the list are faster performance and the flexibility of having the data stored right in SharePoint.  The drawbacks are the that the additional columns of data will increase the size of the list (and content database).  Also, for volatile data that changes often, the cached data will quickly get stale.  As you might guess, the common-sense rule of thumb is to only pull data that does not need real-time status.  However, as you will see, it is easy to refresh the cache.</p>
<p>Just like the Business Data Web Parts, you should consider the cached data in the list as read only, and SharePoint does not give you an interface to change it.</p>
<p>Now that you have a basic idea how this works, let’s take a look at the picture library example that pulls the current product name and inventory value from a database.  For this demonstration, I already have a Products entity defined within an ADF.  I have created a picture library that has three product pictures added.  The All Pictures view looks like this:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image50.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb50.png" border="0" alt="image" width="554" height="137" /></a><br />
Figure 38: Initial View of the Pictures Library</p>
<p>From the Settings menu, let’s add a Business Data column. The column named will be called Product Name as you can see here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image51.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb51.png" border="0" alt="image" width="234" height="266" /></a><br />
Figure 39: Adding a Business Data column called Product Name</p>
<p>When you add a Business Data column, you need to specify the Type, just as you would with the Web Parts.  Below you can see I have selected the Products Type.  I have also added two columns as you can see here</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image52.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb52.png" border="0" alt="image" width="324" height="322" /></a><br />
Figure 40: Selecting the Columns from the Products Type</p>
<p>Notice that you can add as other columns if you like.  I have added the ProductName (the main column in the drop down list) and UnitsInStock which gives us the current inventory value.  After we add these two columns, here is how the All Pictures view now looks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image53.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb53.png" border="0" alt="image" width="504" height="160" /></a><br />
Figure 41: All Pictures View after Adding Business Data Column</p>
<p>This is nice, but you can see that it doesn’t automatically pick up the values from the database.  When you add a Business Data column to a list, you need to map up each item in the list to the matching item in the database.  This is a 1:1 mapping.  Here is how you could manually do this using the UI.  Go to the edit properties for an item, and you’ll see the Business Data column as you see here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image54.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb54.png" border="0" alt="image" width="524" height="74" /></a><br />
Figure 42: Matching up Product Name Item</p>
<p>In the text box, you can type in a unique product name and click the Check Names icon <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image55.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb55.png" border="0" alt="image" width="14" height="12" /></a>.  Or you can also click the Browse icon <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image56.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb56.png" border="0" alt="image" width="15" height="12" /></a> and search for it.  Here is how the browse works:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image57.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb57.png" border="0" alt="image" width="504" height="212" /></a><br />
Figure 43: Finding Matching Row</p>
<p>In the figure above, we are editing the flow regulator picture, so we search for this product by name.  This just executes a search on the Finder method and returns all the products which have this name.  For this product, there’s only one with this name, so we select it.  We are then returned to the edit item page and we accept the changes.  We have now mapped this one product’s picture to its matching database row.  I won’t show you, but I also mapped the other two pictures as well.  When returning to the All Pictures View, you can see that the two columns’ values were pulled from the database and stored in the list:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image58.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb58.png" border="0" alt="image" width="504" height="164" /></a><br />
Figure 44: All Pictures View Now Showing External Data</p>
<p>Remember these values are cached in the list, so when the inventory changes, this will not be automatically reflected in the list.  Without writing code, there is no automated way to refresh this.  It’s very easy for a user to refresh the list, and you do this by clicking the refresh icon <a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image60.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb60.png" border="0" alt="image" width="7" height="11" /></a> listed next to the Product Name column heading.  After clicking refresh, you are greeted with this confirmation page:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/12/image59.png"><img style="0px" src="http://sharepointmagazine.net/wp-content/uploads/2008/12/image-thumb59.png" border="0" alt="image" width="414" height="137" /></a><br />
Figure 45: Updating Cached Business Data in List</p>
<p>In this case, updating three items is minor—if you had thousands (or more) items, it could take a while!  Security Note: If a user only has read permissions to the list, they will still see the refresh icon but will not be able to refresh its data.</p>
<p>Another drawback to this that you might notice is that it can be quite tedious manually mapping up each item in the list to each row in the database.  You may be able to automate some of this through code as I discuss in this <a href="http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=50" target="_blank">blog article</a>.</p>
<p>At this point, you have seen how to add Business Data columns to a SharePoint list.  Now that these are cached within the list, the data stored behaves almost like regular columns.  You can filter, sort, group, all the usual things.  Remember, though, you cannot edit through the list and have the change stored back in the database.  In other words, the synchronization is not two way.  In fact, the columns that BDC adds to the list are read only.</p>
<h4>Wrap Up</h4>
<p>Great job on making it all the way to the end.  You didn’t just skip down here did you?  <img src='http://sharepointmagazine.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   I know this was a long article, but hopefully you were able to go through it quickly, and it gives you a strong grasp on everything you need to know with Business Data Web Parts and incorporating Business Data within your SharePoint lists.</p>
<p>Coming up next in Part 5, we’ll take a close look at how the search engine can crawl BDC data so that your searches encompass your business data as well.  Until then&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-4-of-8/feed</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 3 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8#comments</comments>
		<pubDate>Sun, 14 Dec 2008 12:13:40 +0000</pubDate>
		<dc:creator>Randy Williams</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[MOSS]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=1728</guid>
		<description><![CDATA[Welcome to part three of our BDC series.  In this article our focus will be on consuming Web Services from BDC.  It will cover the value of Web Services, how to develop the Web Services to be BDC capable, and introduce how the Application Definition File describes these Web Services.  ]]></description>
			<content:encoded><![CDATA[<p>Welcome to part three of our BDC series.  In this article our focus will be on consuming Web Services from BDC.  It will cover the value of Web Services, how to develop the Web Services to be BDC capable, and introduce how the Application Definition File describes these Web Services.  We will building on what we learned in the first two articles, so if you’re still learning BDC and haven’t gone through those yet, you are encouraged to go back and read them.  Since this article covers the programming of Web Services, it will be more developer-oriented.</p>
<h4>Why Web Services</h4>
<p>While relational databases have proliferated greatly over the last 20 years, there are some inherent difficulties with them.  For starters, they are often proprietary.  While structured query language (SQL) is an ANSI-standard language, vendors choose to develop their own flavor of SQL such as PL-SQL with Oracle or T-SQL with Microsoft.  In order to query from a database, you need a vendor-specific driver, making integration between systems difficult.  Furthermore, the network connection is often based on remote procedure calls (or RPCs) that won’t typically work over an HTTP connection.  This makes connecting to them over the Internet or through firewalls a challenge.</p>
<p>Web Services have matured in the last few years as the de-facto way of integrating systems together.  Service-oriented architecture (<a href="http://en.wikipedia.org/wiki/Service-Oriented_Architecture" target="_blank">SOA</a>), which is based on Web Service technology, offers us a very compelling approach to building and integrating systems today.  Its loosely-coupled nature and vendor-neutral design make it far more flexible and practical for the changing needs of organizations.  Exposing line of business data over Web Services gives you more control, more universal access, HTTP compatibility, and is in line with emerging technologies such as cloud computing.</p>
<p>Since a primary goal of SharePoint is to be the central interface for critical data assets, it’s likely that SharePoint will need to integrate with external systems.  In article two of this series, we covered how the ADF can describe an external database.  In addition to the advantages we just covered, there may be other reasons why Web Services might be the better choice.  For example, perhaps you already have a Web Services architecture in place that you want to leverage.  Or you have data that comes from a myriad of data sources such as databases, XML files, or services in the Internet cloud.  With Web Services, your content can originate in virtually any source.  By exposing these data sources through a Web Service, you provide a single way for SharePoint to consume this data, regardless where it is located.  This is depicted in Figure 1 here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image16.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb10.png" border="0" alt="image" width="370" height="204" /></a><br />
<strong>Figure 1: Exposing Web Services to MOSS</strong></p>
<h4>Developing Your Web Services</h4>
<p>Now that we have covered why Web Services might be right technology, let’s dive into a sample Web Service that we can consume from BDC.  As you can see in Figure 1 above, the data can originate from any back-end data source.  In this first example, it will come from the AdventureWorks database from a Microsoft SQL Server.  The data we want will be returned using a simple stored procedure named GetEmployees.  Here is the code for the stored procedure:</p>
<div class="wp_syntax">
<div class="code">
<pre><span><span style="color: #0000ff;">create</span> <span style="color: #0000ff;">proc</span> [dbo].[GetEmployees]</span>
<span><span style="color: #0000ff;">as</span></span>
<span><span style="color: #0000ff;">select</span> Employee.EmployeeID,</span>
<span>        Contact.FirstName,</span>
<span>        Contact.LastName,</span>
<span>        Employee.Title,</span>
<span>        Employee.HireDate</span>
<span><span style="color: #0000ff;">from</span> HumanResources.Employee</span>
<span><span style="color: #0000ff;">join</span> Person.Contact</span>
<span><span style="color: #0000ff;">on</span> Employee.ContactID = Contact.ContactID</span></pre>
</div>
</div>
<p>As you can see, we are returning four columns.  We join from the Employee to the Contact table to retrieve all the columns we need.  We then call into this stored procedure from our C#-based Web Method.  This method is coded within an ASP.NET Web Service project as shown here:</p>
<div class="wp_syntax">
<div class="code">
<pre><span>[WebMethod]</span>
<span><span style="color: #0000ff;">public</span> <span style="color: #2b91af;">List</span>&lt;Employee&gt; GetEmployees()</span>
<span>{</span>
<span>    Database db = DatabaseFactory.CreateDatabase(<span style="color: #a31515;">"Connection String"</span>);</span>
<span>    IDataReader employeesReader;</span>
<span>    <span style="color: #2b91af;">List</span>&lt;Employee&gt; employees = <span style="color: #0000ff;">new</span> <span style="color: #2b91af;">List</span>&lt;Employee&gt;();</span>

<span>    DbCommand cmd = db.GetStoredProcCommand(<span style="color: #a31515;">"GetEmployees"</span>);</span>

<span>    employeesReader = db.ExecuteReader(cmd);</span>
<span>    <span style="color: #0000ff;">while</span> (employeesReader.Read())</span>
<span>    {</span>
<span>        employees.Add(<span style="color: #0000ff;">new</span> Employee((<span style="color: #0000ff;">int</span>)employeesReader[<span style="color: #a31515;">"EmployeeID"</span>],</span>
<span>                      employeesReader[<span style="color: #a31515;">"FirstName"</span>].ToString(),</span>
<span>                      employeesReader[<span style="color: #a31515;">"LastName"</span>].ToString(),</span>
<span>                      (<span style="color: #2b91af;">DateTime</span>)employeesReader[<span style="color: #a31515;">"HireDate"</span>]));</span>
<span>    }</span>
<span>    employeesReader.Close();</span>

<span>    <span style="color: #0000ff;">return</span> employees;</span>
<span>}</span></pre>
</div>
</div>
<p>Version 4.1 of the <a href="http://msdn.microsoft.com/en-us/library/dd203144.aspx" target="_blank">data access application block</a> from the Enterprise Library is used to return the Employee data.  This is not required as any form of ADO.NET code will work, but this simplifies our data retrieval and is a good practice.  The data returned from the Web Method is a generic list based on the Employee class.  You can consider this Employee class to be our business object representing a single employee.  Here is the part of the class with the four columns and two constructors.</p>
<div class="wp_syntax">
<div class="code">
<pre><span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> Employee</span>
<span>{</span>
<span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span> _id;</span>
<span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _first;</span>
<span>    <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> _last;</span>
<span>    <span style="color: #0000ff;">private</span> <span style="color: #2b91af;">DateTime</span> _hireDate;</span>

<span>    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> ID</span>
<span>    {</span>
<span>        <span style="color: #0000ff;">get</span> { <span style="color: #0000ff;">return</span> _id; }</span>
<span>        <span style="color: #0000ff;">set</span> { _id = <span style="color: #0000ff;">value</span>; }</span>
<span>    }</span>
<span>    <span style="color: #008000;">//Additional getter/setter for remaining columns go here </span></span>

<span>    <span style="color: #0000ff;">public</span> Employee(<span style="color: #0000ff;">int</span> id, <span style="color: #0000ff;">string</span> first, <span style="color: #0000ff;">string</span> last, <span style="color: #2b91af;">DateTime</span> hireDate)</span>
<span>    {</span>
<span>        <span style="color: #0000ff;">this</span>._id = id;</span>
<span>        <span style="color: #0000ff;">this</span>._first = first;</span>
<span>        <span style="color: #0000ff;">this</span>._last = last;</span>
<span>        <span style="color: #0000ff;">this</span>._hireDate = hireDate;</span>
<span>    }</span>

<span>    <span style="color: #0000ff;">public</span> Employee()</span>
<span>    {</span>
<span>        <span style="color: #0000ff;">this</span>._id = 0;</span>
<span>        <span style="color: #0000ff;">this</span>._first = <span style="color: #0000ff;">string</span>.Empty;</span>
<span>        <span style="color: #0000ff;">this</span>._last = <span style="color: #0000ff;">string</span>.Empty;</span>
<span>        <span style="color: #0000ff;">this</span>._hireDate = <span style="color: #2b91af;">DateTime</span>.Parse(<span style="color: #a31515;">"1/1/2000"</span>);</span>
<span>    }</span>
<span>}</span></pre>
</div>
</div>
<p>One key advantage of using a generic list when writing the Web Method is that it serializes nicely into XML.  It also describes the complex types in the XML Schema (<a href="http://en.wikipedia.org/wiki/XML_Schema_(W3C)" target="_blank">XSD</a>) in a BDC-friendly way which will make the authoring of the ADF file much easier.  When Employees are returned from the Web Method, here is how one of them will be described in XML:</p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image32.png" border="0" alt="image" width="329" height="112" /></p>
<p><strong>Figure 2: Employee element returned from Web Service</strong></p>
<p>In the Web Service, we also define two additional methods, one for an IdEnumerator and one for a Specific Finder.  For brevity sake, I only show the interface for each.  They are coded similarly, and you can download the full code at the end of this article.</p>
<div class="wp_syntax">
<div class="code">
<pre><span><span style="color: #0000ff;">public</span> <span style="color: #2b91af;">List</span>&lt;<span style="color: #0000ff;">int</span>&gt; GetEmployeeIDs () <span style="color: #008000;">//IdEnumerator </span></span>
<span><span style="color: #0000ff;">public</span> Employee GetEmployeeByID(<span style="color: #0000ff;">int</span> EmployeeID) <span style="color: #008000;">//Specific Finder</span></span></pre>
</div>
</div>
<p>GetEmployeeIDs (the IdEnumerator) just returns the ID for each Employee.  The Specific Finder returns a single Employee object based on the supplied EmployeeID.</p>
<h4>Creating the Application Definition File</h4>
<p>Now that we have defined a simple Web Service exposing employees, let’s look at how this is represented in our ADF.  Since the basic structure of the ADF remains the same with a Web Service as compared to a database, we’ll only focus on the areas that pertain to calling Web Services.</p>
<p>In Figure 3 below is our LobSystem element which is the root of the ADF.  You’ll notice that the Type attribute indicates WebService.  Inside Properties, a namespace prefix is defined for this LOB.  In our case, we call this HR (for Human Resources).  We also set the URL to the Web Service.  When this ADF is loaded into MOSS, the Web Services Description Language (<a href="http://en.wikipedia.org/wiki/Web_Services_Description_Language" target="_blank">WSDL</a>) for this URL is retrieved and an internal proxy class is generated that BDC uses.  This concept is very similar when adding a Web Reference to a Visual Studio project.</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image17.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb11.png" border="0" alt="image" width="704" height="109" /></a></div>
<p><strong>Figure 3: LobSystem Root Element in ADF</strong></p>
<p>Moving down in the schema we find our LobSystemInstance which is where connection details are specified.  For a Web Service, there are several options such as how to authenticate and how many simultaneous connections are allowed.  In our case, our needs are simple, so we only need to list the name of our LobSystem which is HR.  (Note: since we didn’t specify how to authenticate, this will use RevertToSelf settings which means that the application pool identity will be the credentials used if the Web Service requires authentication.)</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image18.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb12.png" border="0" alt="image" width="454" height="98" /></a></div>
<p><strong>Figure 4: LobSystemInstances in ADF</strong></p>
<p>Where it gets interesting is how we start to define our methods for each entity.  The secret to writing the Web Service-based ADF is to define the TypeDescriptor elements correctly.  Each TypeDescriptor points to an element node in the Web Service XML request or response, and the basic rule is that you need to nest your TypeDescriptors to match the hierarchy.  For example, here is our Finder method that will call the GetEmployees Web Method and return a list of Employees.</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image19.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb13.png" border="0" alt="image" width="544" height="222" /></a></div>
<p><strong>Figure 5: Return Parameter for GetEmployees Web Method</strong></p>
<p>Let’s go through what we’re seeing here.  First off, the Name attribute for the Method must match the name of the Web Method.  In this example, it is GetEmployees, which we introduced above.  The TypeDescriptor elements that are highlighted reflect our hierarchy in the response.  The first one defines an array of Employee elements (denoted in part by the IsCollection=”true”).  The second one defines each Employee, and the final four define each column that is returned.  In a snippet of the actual XML response shown in Figure 6 below, notice the Name attribute for the TypeDescriptor matches the Element name.  This name match-up is not required in all cases but is recommended.</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image20.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb14.png" border="0" alt="image" width="484" height="126" /></a></div>
<p><strong>Figure 6: Actual XML Response from Web Service (GetEmployees Method)</strong></p>
<p>Let’s look at one more example.  Here is our IdEnumerator which returns the IDs for all Employees.  Here is the method we define in the ADF:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image21.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb15.png" border="0" alt="image" width="504" height="137" /></a></p>
<p><strong>Figure 7: ADF Entry for IdEnumerator</strong></p>
<p>In this case, we return an array of Int32 (32-bit Integers).  Below, here is the first part of the the corresponding XML that is returned from the Web Service.  Notice how the two levels in the XML, ArrayOfInt and int, align (i.e. int is a child element of ArrayOfInt).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image22.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb16.png" border="0" alt="image" width="484" height="98" /></a></p>
<p><strong>Figure 8: Actual XML Response from Web Service (GetEmployeeIDs Method)</strong></p>
<h4>Consuming Employees from UI</h4>
<p>So now that we have our Web Service ready, and our ADF loaded and secured within our SSP (as covered in the Article #2), it’s time to see the what this effort yields us in the user interface.  Let’s first take a look at the Business Data List Web Part.  We will examine this Web Part in more detail in the next article, but for now, here is a basic view of the Employee entity from our catalog:</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image23.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb17.png" border="0" alt="image" width="404" height="279" /></a></div>
<p><strong>Figure 9: Employees showing in a Business Data List Web Part</strong></p>
<p>Here is a recap of how this executes:  These records are pulled in real time through a proxy class created from the ADF, through the Web Service and into the stored procedure running inside SQL Server.  Since we have defined IdEnumerator and Specific Finder methods, we can also set up a Content Source and crawl this BDC data.  This allows us to issue search queries against the external system, and this will be covered in depth in Article 5.  For now, I have set this up with the Employee entity in the ADF, and this is the result when we search for Rob (someone’s first name):</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image24.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb18.png" border="0" alt="image" width="354" height="208" /></a></div>
<p><strong>Figure 10: Search Results for Employees Based on Name</strong></p>
<p>And finally, let’s look at an auto-created profile page.  This is created by the BDC that allows us to view all the details for a single record.  These types of pages will be covered in more detail in Article 8.</p>
<div><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image25.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb19.png" border="0" alt="image" width="374" height="298" /></a></div>
<p><strong>Figure 11: Profile Page for a Single Employee</strong></p>
<p>With that, you should have a basic idea in how the ADF needs to match the response from the Web Service.  If you’ll be developing these ADFs from scratch, I advise you to look at the WSDL provided by the Web Service to understand the Complex Types in the XSD.  I also recommend looking at the actual XML data that is coming back.  From here, and with some practice, you will be able to construct your ADFs.  The process for input parameters (for example, with FilterDescriptors) is the same.</p>
<h4>Amazon Web Service</h4>
<p>The second example we’ll look at is a bit more complex.  Within the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=6D94E307-67D9-41AC-B2D6-0074D6286FA9" target="_blank">MOSS SDK</a>, a sample ADF file exists to call into Amazon to do a search for a product.  This is quite powerful and great demonstration of services in the cloud.  For this section, we will look at a modified form of the sample ADF, so even if you’ve seen this, I recommend you keep reading.  Let’s first show you how this looks from the user’s perspective.  I have added a Business Data List Web Part to a web page and have pointed it to the Amazon entity in the catalog.  Here is how it shows the results when searching for SharePoint books:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image26.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb20.png" border="0" alt="image" width="718" height="309" /></a> <strong>Figure 12: Keyword Search Against Amazon Web Service </strong></p>
<p>As you can see, it has returned the first ten titles which match these keywords.  The book’s ISBN and Title are shown, and Title links to the actual book URL on Amazon’s web site.  This was done by pulling the raw data from Amazon through the BDC and displaying it with a custom <a href="http://en.wikipedia.org/wiki/XSLT" target="_blank">XSLT</a> Stylesheet.</p>
<p>To understand how this works, let’s first understand the XML that will be delivered to BDC.  Here is what a single book (an Item) looks like in the XML Response from the Web Service (Note: I have collapsed the ItemLinks element since it’s not used in this demonstration):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image27.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb21.png" border="0" alt="image" width="644" height="173" /></a> <strong>Figure 13: Actual XML Response from Amazon Web Service </strong></p>
<p>As you can see, we have the ISBN returned in an element called ASIN.  We also have URL stored in the DetailPageURL element.  Lastly, details about the book are stored in a child element called ItemAttributes, and this is where we need to extract the book’s title.  Taking a look at the XSD defined in the WSDL provided by Amazon, we see the definition for each Item and ItemAttributes.  (Note: I have edited the file to only focus on these two complex types).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image28.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb22.png" border="0" alt="image" width="554" height="289" /></a></p>
<p><strong>Figure 14: A Selected Portion of Amazon’s Web Service WSDL</strong></p>
<p>Now that we know what we’re dealing with in terms of schema, let’s see how the ADF comes together.  Again, I have modified the sample Amazon ADF file.  Specifically, I have removed an unused entity, and added additional logic to expose the book’s title.  Here is our single entity, called Item.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image29.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb23.png" border="0" alt="image" width="474" height="189" /></a></p>
<p><strong>Figure 15: Item Entity Defined in ADF</strong></p>
<p>Keywords is the friendly name for our filter as you can see in the screenshot in Figure 12 above.  As part of the input parameters, we provide the value of this Keyword, a subscription ID (required by Amazon to call into the Web Service), and some default values for what we’re searching (Books in this example).  These won’t be shown for brevity sake.  The concept for these input parameters is the same as the returned output in that you must define hierarchical TypeDescriptor elements to match the XML request.  With that, let’s focus on the returned response.  The hierarchy here is pretty deep, so we’ll just focus on the inner-most section that begins with an array of items.  Here is how this looks:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image33.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb25.png" border="0" alt="image" width="704" height="372" /></a> <strong>Figure 16: TypeDescriptor Hierarchy for Returning Items</strong></p>
<p>It might look imposing at first glance, but if you follow the arrows, you can see how this maps up with the actual XML response shown in Figure 13 above.  The tricky part with this example is that we want to return Title to be at the same level as ASIN (the ISBN) and DetailPageURL.  In the XML response, Title is nested in a child node called ItemAttributes.  This becomes a problem because we need to return a flat set of columns and rows just like in a sheet in Excel.  In our case, the desired columns are ISBN, DetailPageURL and Title.  In other words, hierarchies are not allowed.  So, we somehow need to “promote” Title up one level.</p>
<p>We solve this problem by first setting a localized name for ItemAttributes to be Title.  This just means we rename this column to Title.  To get the actual value for Title, we use what’s called ComplexFormatting.  ComplexFormatting allows us to generate the value, and we do this using the FormatString property.  The {0} (just as with the String.Format method) will generate a new string from the value of a child element called Title.</p>
<p>With this described ADF, we have now effectively mapped the fairly complex result from Amazon into a pretty simple display.  If we load the ADF as is and add a Business Data List Web Part that points to this Item entity, we get the following result:</p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image31.png" border="0" alt="image" width="717" height="180" /> <strong>Figure 17: Raw Output of our Item Entity</strong></p>
<p>Here are our three columns, ISBN, DetailPageURL and Title.  Of course, we would like the Title to just be a hyperlink to the specified URL.  We can handle this with a small change to the Web Part’s XSLT.  This is what yields the display shown in Figure 12.</p>
<h4>Recommendations</h4>
<p>Now that you have a pretty good idea how to structure your own, let me leave you with some recommendations that should help you construct your Web Service-based ADFs.</p>
<ul>
<li>The BDC only supports Simple Object Access Protocol (<a href="http://en.wikipedia.org/wiki/SOAP_(protocol)" target="_blank">SOAP</a>)-based Web Services, not <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer" target="_blank">REST</a>-ful (REpresentational State Transfer) ones.</li>
<li>Due to the structure of the ADF files, you will not easily be able to consume existing Web Services unless they closely match the concepts of Finder, Specific Finder, and IdEnumerator.  You might find yourself having to write specific Web Services, which is why I provided a sample on how this can work.</li>
<li>If your Web Services are developed using the approach used above, you should have some success working with ADF generation tools like BDC Design Studio, BDC Meta Man, and BDC Definition Editor.  If not, you will likely need to generate the ADFs by hand.  Even when some design tools, the effort is more involved as the utility cannot infer the Identifier or FilterDescriptors for entities.  In some cases, you might get part of the ADF described using a tool, and then you’ll need to go in and make some tweaks to it.</li>
<li>If you find yourself needing to write a lot of Web Service wrappers around your existing databases, you might find a utility from the same company that makes BDC Meta Man helpful.  It’s called BDC Web Man, and you can find it <a href="http://www.lightningtools.com/bdc-web-man/default.aspx" target="_blank">here</a>.</li>
<li>Keep your returned Web Service XML structures simple.  As you can see, deep hierarchies are much harder to represent in the ADF.  You’ll probably find it much easier to adjust the Web Service output than trying to craft the ADF to work with a complex structure.  For example, while you can return and consume a DataSet in the ADF, the amount of nesting makes this a very complex task, and you’ll need to code it all by hand.</li>
<li>As much as possible, review the WSDL file and actual XML results when structuring the ADF file.  This will help ensure you are representing your TypeDescriptor hierarchies correctly.</li>
<li>If you are developing new Web Services using .NET technologies, you can use either classic Web Services (i.e. ASMX) or the newer Windows Communications Framework (WCF) style, provided you configure it to support SOAP.</li>
<li>Since your Web Service WSDL will be downloaded and parsed when you load the ADF into your SSP, make sure the Web Service is physically accessible at that time.</li>
<li>Authenticating to the Web Service through HTTP or SOAP headers is supported through the BDC.  See the following <a href="http://msdn.microsoft.com/en-us/library/bb802855.aspx" target="_blank">article</a> from the MOSS SDK for details on how this works.</li>
<li>When troubleshooting problems with your ADF, be sure to check both the Windows Application EventLog and SharePoint’s diagnostic log files (C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\LOGS).  These will provide you with much more detail on the nature of the problem.</li>
<li>As I’ve suggested, you want to review the actual XML results from your Web Services.  These can be difficult to capture at times.  To help, you might find some value in using a network sniffer such as Network Monitor.  This allows you to capture the actual network packets allowing you to study the traffic between the SharePoint server and the Web Service server.  You can download Microsoft’s Network Monitor for free from <a href="http://www.microsoft.com/downloads/details.aspx?familyid=f4db40af-1e08-4a21-a26b-ec2f4dc4190d" target="_blank">here</a>.</li>
</ul>
<h4>Download Sample Code</h4>
<p>In the sample code available <a href="http://sharepointhawaii.com/randywilliams/Files/BDCArticle3Code.zip" target="_blank">here</a>, you will find the following code:</p>
<ul>
<li>Amazon ADF (Note: you will need your own <a href="http://aws.amazon.com/" target="_blank">Amazon Web Service</a> (AWS) Account)</li>
<li>Modified Amazon XSLT for the Business Data List Web Part</li>
<li>The complete Employee Web Service (VS.NET 2008 project)</li>
<li>The Employee ADF</li>
<li>Employee Stored Procedures for <a href="http://www.codeplex.com/MSFTDBProdSamples" target="_blank">AdventureWorks database</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-3-of-8/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 2 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8#comments</comments>
		<pubDate>Wed, 26 Nov 2008 06:39:32 +0000</pubDate>
		<dc:creator>Randy Williams</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[adf]]></category>
		<category><![CDATA[application]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[definition]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=1532</guid>
		<description><![CDATA[In this article, the emphasis will be on the Application Definition File (or ADF).  We’ll make sure you have a good understanding of the role it plays, how it works, and a give you a good overview of the XML schema that is used.]]></description>
			<content:encoded><![CDATA[<p>Welcome back.  This is part two of an eight part series on BDC.  In the first article, I gave you an overview of the BDC from a business standpoint and introduced its architecture.  In this article, the emphasis will be on the Application Definition File (or ADF).  We’ll make sure you have a good understanding of the role it plays, how it works, and a give you a good overview of the XML schema that is used.  We’ll then look at various ways you can create these ADFs, show you how to publish them into your farm, and also cover how security on the ADF is managed.  We have a lot to cover, so let’s get started.</p>
<h4>ADF Overview</h4>
<p>Since we understand the BDC to be a middle man between the user interface and some back-end system, we need some way of mapping how the back end system is structured.  This mapping can then be consumed from the various interfaces such as Web Parts and searching that we covered in the last article.  Since BDC is designed to pull data from virtually any relational database or SOAP-based Web Service, you’d correctly guess that the ADF must be flexible and generic in nature.  As mentioned already, the ADF is an XML file with a specific schema and its concept can be likened to a logical database diagram.  By logical, I mean that it does not have any vendor-specific features such as data types.  Keep in mind that it must also be flexible enough to connect to Web Services as well, so it can’t be too database-centric as well.</p>
<p>XML makes good sense for the definition as it is a declarative way to define the back-end in a generic way.  By being declarative, and not done programmatically through code, it helps ensure that we have a loosely-coupled design.  This is very important as front-ends and back-ends are likely to change, and we want to make sure the maintenance effort spent on this middle layer is minimized.  As we’ll see later, having it XML based also makes it easier to automatically generate this definition.</p>
<p>In Figure 1 below, you can see a conceptual overview of how the ADF is used.  The browser makes a regular request where BDC data is needed (e.g. a BDC Web Part, Search, etc.).  The MOSS web front end receives the request, and as part of its processing, hands the BDC request off to the Object Model. The Object Model (also known as the API or Application Programming Interface) gets the definition for this ADF from its catalog.  With the details on the ADF known, the Object Model requests the data from the database or Web Service.  The response is returned and then formatted as appropriate for delivery back to the browser.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image7.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb1.png" border="0" alt="image" width="280" height="322" /></a><br />
<strong>Figure 1: Data flow overview with BDC</strong></p>
<p>To best understand the ADF, it helps to have an understanding of some of the terminology used.  This will relate directly to structures found in the XML definition.  Those with a database background (and also those developers with knowledge of ADO.NET) should pick these concepts up right away.</p>
<p><strong>Line of Business</strong>.  Line of business (or LOB) is just a term that refers to a back-end system.  As you’ll see shortly, a single ADF is comprised of one or more LOB instances.</p>
<p><strong>Entity</strong>.  An entity works like a table.  The entity term is also used when designing a logical database diagram, and the concept is the same.</p>
<p><strong>Method</strong>.  A method is how we request data (or query) from an entity.  For a database, it is usually a SQL select statement or stored procedure.  For a Web Service, it would be a Web Method.  Each entity supports multiple methods.</p>
<p><strong>Parameter</strong>.  Parameters are the inputs and outputs to a method.  Each parameter has a name and a .NET data type (e.g. System.Int32 or System.String).</p>
<p><strong>Filter Descriptor</strong>.  Filter descriptors provide an easy way for users to filter records (rows) found in an entity.  It is mostly commonly used with the Business Data List Web Part.  For example, you might want to allow users to quickly find a company by its name.</p>
<p><strong>Association</strong>.  Associations are how relationships are represented.  For example, an Employee entity might have an association with a VacationRequest entity.  For a database, these are normally used on child tables that have a foreign key.</p>
<p><strong>Action</strong>. Actions are used with entities and allow you to link to external applications or custom SharePoint pages for additional processing.  These are commonly used in write-back situations, and we will look closer at these in the final article in this series.</p>
<h4>The ADF Schema</h4>
<p>Now that you have a pretty good idea of what the ADF does and some of the vocabulary, let’s go ahead and examine the XML Schema for an ADF.  (Note: this is not intended to be a detailed discussion; for a deeper look, please consult the MOSS SDK (Software Development Kit) here: <a title="http://msdn.microsoft.com/en-us/library/ms563661.aspx" href="http://msdn.microsoft.com/en-us/library/ms563661.aspx">http://msdn.microsoft.com/en-us/library/ms563661.aspx</a>.)  One of the screen shots from this SDK is very helpful in understanding the high-level hierarchy of the ADF.  You can see it here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image8.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb2.png" border="0" alt="image" width="520" height="313" /></a><br />
<strong>Figure 2: ADF Schema Overview</strong></p>
<p>LobSystem is the root element in the ADF file.  It contains attributes to the required namespaces, specifies whether it is a Web Service or Database, and sets the Name of the ADF.</p>
<p>LobSystemInstance is where you define your connection in the ADF.  Even though the XML schema looks like it supports multiple connections, you can only have a single connection defined in your ADF.  Through Property child elements, you define the connection string to this data source.  Those with ADO.NET experience will quickly recognize this example below as a Windows-integrated login to a SQL Server.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image35.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image35-thumb.png" border="0" alt="image" width="554" height="120" /></a><br />
<strong>Figure 3: LobSystemInstance</strong></p>
<p>The details of authentication is a complex subject, and we’ll just cover the basics here.  When connecting, you have four options when it comes to authentication.</p>
<p>1) <strong>PassThrough</strong>.  PassThrough can be used to authenticate the user in one of two ways, using Windows credentials or database credentials. With Windows (shown in Figure 3 above), the client&#8217;s Windows credentials are forwarded to the back end system.  This can be used for both databases and Web Services.  The problem with this, however, is that unless you&#8217;re using Kerberos (or your Web Service/database server is on the same physical machine as your SharePoint web front end), this will fail.  This is due to Windows NT Lan Manager&#8217;s (NTLM) inablility to delegate.  With database credentials, you use a database-specific username and password to log in.  This can only be used against a database server, not a Web Service.</p>
<p>2) <strong>RevertToSelf</strong>. This means the credentials of the Application pool is used to authenticate the user.  This will solve the the delegation problem from above, but all users will effectively use the same login on the back end.</p>
<p>3) <strong>WindowsCredentials/RDBCredentials</strong>.  These are used in conjunction with Single Sign On (SSO).  In this model, the user’s credentials (either a Windows login or a database-specific login) for the external system are pulled from the SSO database.</p>
<p>4) <strong>Credentials</strong>.  This is only used if you are connecting to a Web Service and cannot use Windows authentication.</p>
<p>For more details on authentication, I recommend you start your reading here:  <a title="http://msdn.microsoft.com/en-us/library/ms566523.aspx" href="http://msdn.microsoft.com/en-us/library/ms566523.aspx">http://msdn.microsoft.com/en-us/library/ms566523.aspx</a>.</p>
<p>Within LobSystemInstance, each entity for this connection is defined.  The entity itself is not very interesting as it just defines a friendly name by which users will reference it.  Within each entity, you define an identifier and methods.  An identifier is the primary key, or the column(s) from the entity that can be used to uniquely identify each row.  These are very important as they are used in a number of ways.  Often, these are ID columns, such as CustomerID as shown here.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image41.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image41-thumb.png" border="0" alt="image" width="359" height="42" /></a><br />
<strong>Figure 4: Identifier</strong></p>
<p>Also part of each entity are the methods.  These are really the heart of the ADF as it defines the actual data that will be pulled.  It is where you specify a select statement (e.g. <em>select * from table</em>), a stored procedure, or a Web Method if it’s a Web Service.  Since there may be multiple ways to query data from an entity, you can have multiple methods.  Here is a simple example with returning a few columns from a table named Customers.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image49.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image49-thumb.png" border="0" alt="image" width="489" height="100" /></a><br />
<strong>Figure 5: Method</strong></p>
<p>Within a method, you may want to define one or more ways in which this method can be filtered by users.  This is used within the BDC Web Parts.  For example, for the list of customers above, imagine your company has hundreds of them.  How will your users easily find the one they are looking for?  Start by asking yourself what are the common ways they might want to lookup a customer—perhaps by Name, by Region, or by a Contact Name.  If this makes sense then you understand FilterDescriptors.  Here is a simple look at two FilterDescriptor entries that have been made.  The Name attribute you see here defines the friendly name that users will work with, so make sure this name makes sense to them.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image55.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image55-thumb.png" border="0" alt="image" width="367" height="59" /></a><br />
<strong>Figure 6: FilterDescriptor</strong></p>
<p>Now that you understand filtering, let’s go back to methods for a bit.  In the ADF, there are different types of methods, and the three primary types we work with are Finder, SpecificFinder and IdEnumerator.  Finder methods are used when you want to return one or more rows from an entity.  For example, find all customers who are in the North America region.  SpecificFinder is used to find a single row and is used in conjunction with the Identifier mentioned above. For example, find me the one Customer that has CustomerID = 42.  IdEnumerator is used to return the identifier value for each row.  In code terms, this would look something like <em>Select CustomerID from Customers</em>.  The BDC uses this when crawling for Enterprise Search integration.  You will find each method type defined within a MethodInstance.</p>
<p>Let’s move on to Parameters.  Parameters allow you to describe the exact input and output for methods.  Input parameters (Direction = “In”) are used with Filter Descriptors.  There are different types of output parameters, but the most common are Return parameters (Direction = “Return”).  These are used to describe each column that is returned from a method.  For each parameter, you define the friendly name and its .NET-matching data type.  In Figure 7 below, we see the two parameters that are defined for our two FilterDescriptors above.  These are input parameters as shown here:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image61.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image61-thumb.png" border="0" alt="image" width="534" height="213" /></a><br />
<strong>Figure 7: Parameter</strong></p>
<p>Last but not least, let’s cover Associations.  We use Associations to define the actual relationships that exist in the external system.  BDC can directly work with one-to-one and one-to-many types of relationships.  When you define an Assocation, you define the SourceEntity (i.e., the parent or primary) and the DestinationEntity (i.e., the child or foreign).  You also must point to a method in the child entity that returns all the child rows based on a single parent row.  This method will usually “join” these two tables together.  In SQL terms, it would be something like</p>
<p><em>Select * from Orders<br />
join Customers on Orders.CustomerID = Customers.CustomerID<br />
where Orders.CustomerID = 42</em></p>
<p>Here is an example on how an Association is defined in the ADF:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image68.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image68-thumb.png" border="0" alt="image" width="704" height="74" /></a><br />
<strong>Figure 8: Association</strong></p>
<p><strong></strong></p>
<h4></h4>
<h4>Creating ADFs</h4>
<p>In the small snippets above, you can probably see that the XML syntax won’t likely roll off your fingertips.  It takes time and practice to get good at writing them.  These can be created in any text or XML editor, including Visual Studio.  If you will be using Visual Studio, I recommend you import the BDCMetaData.xsd schema file so at least you get IntelliSense.  You can follow the guidance on how to set this up from SharePoint MVP Andrew Connell <a href="http://www.andrewconnell.com/blog/archive/2006/10/20/4944.aspx">here</a>.</p>
<p>Fortunately, there are tools out there that can reverse engineer the database (or Web Service) and generate most if not all of the ADF file for you. Even if you only have to write one ADF, these tools may be worth it.  The three main ones available to you are</p>
<ul>
<li>BDC Definition Editor</li>
<li>MOSS BDC Design Studio</li>
<li>BDCMetaMan</li>
</ul>
<p>BDC Definition Editor is free and comes from Microsoft.  You can install it after you install the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=6D94E307-67D9-41AC-B2D6-0074D6286FA9">MOSS SDK</a>.  Sadly, with this tool, you get what you pay for.  It doesn’t generate Finder methods, crashes quite a lot, and requires you to install SQL Server 2005 Express (even if you have a full SQL Server instance installed).  It’s certainly better than nothing but not recommended for regular use.</p>
<p><a href="http://www.simego.net/MOSS_BDC_Design_Studio.aspx">MOSS BDC Design Studio</a> is a commercial product from Simego.  The latest version 2.0 has a nice wizard interface when setting up each entity.  It can be used to generate ADFs on common databases like SQL Server and Oracle as well as Web Services. It is reasonably priced at $200 for a single license.</p>
<p><a href="http://www.lightningtools.com/bdc-meta-man/default.aspx">BDCMetaMan</a> from Lightning Tools is the top-of-the-line and de-facto standard for generating ADFs.  It is well written and fully featured.  It is also the most expensive at $1200 per license but well worth it if you use it enough.</p>
<h4>Loading the ADF into MOSS</h4>
<p>Once your ADF file has been generated, it needs to be loaded into your SharePoint environment.  This is done through your Shared Services Provider (SSP).  To get there from Central Administration, click on your SSP name in the Quick Launch menu on the left, then click Import application definition in the Business Data Catalog section.  Loading it is as simple as browsing to the file and clicking the Import button.  When you upload the ADF, it will validate the XML file. It will then create entries in your SSP Database for each LobSystemInstance and Entity.</p>
<p>Once the ADF is loaded, you might want to take a look at its structure.  Just click on View applications from the main SSP screen, and then navigate down through your named ADF and into each entity.  With the exception of custom actions, everything else is read only, so you can’t really make any changes.</p>
<h4>Setting Permissions</h4>
<p>When you’re done poking around, you’ll probably want to set permissions on your new definition.  Permissions apply to these levels in the ADF hierarchy: LobSystem (the whole ADF), Entity, Method and MethodInstance.  This means you can secure at a high level such as each ADF, or very granularly such as each Method within an Entity.  Unfortunately, the administration GUI only lets you set permissions down to the Entity level, so this is the lowest level that most people work with. You can also set permissions at a higher level (even the whole BDC) and copy these down to lower levels.  When setting permissions, you have four permissions to choose from.  Each is introduced here:</p>
<ul>
<li><strong>Edit</strong>.  This permission allows you to delete or add new ADFs into BDC.  You would grant this to those who would be uploading new ADFs into your SSP.</li>
<li><strong>Execute</strong>.  This allows you to execute Method Instances.  If you apply this permission at the entity level, it applies to all methods and method instances for this entity.</li>
<li><strong>Select in Clients</strong>.  This defines whether you can see the entity when configuring BDC Web Parts or adding a BDC column to a list.</li>
<li><strong>Set Permissions</strong>.  This allows you to change permissions for other users at the various levels as described in this section.</li>
</ul>
<p>That said, the common approach is to give users both the Execute and Select in Clients permission for all entities that they will be working with.  As standard with SharePoint, you can assign permissions to Users or Groups.</p>
<p>With that, we bring this Part Two article to a close.  By now, you should have a solid understanding of how BDC works and how to create, load and secure your ADF entities.  In the next session, we’ll focus more on creating ADFs for Web Service systems.  From there, we’ll then move over to the UI and how to leverage the value that these ADF entries give you.</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-2-of-8/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Everything You Need to Know about BDC: Part 1 of 8</title>
		<link>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8</link>
		<comments>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8#comments</comments>
		<pubDate>Sun, 16 Nov 2008 19:55:39 +0000</pubDate>
		<dc:creator>Randy Williams</dc:creator>
				<category><![CDATA[Administration]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Business Data Catalog]]></category>
		<category><![CDATA[Business Intelligence]]></category>
		<category><![CDATA[MOSS]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=1647</guid>
		<description><![CDATA[Welcome to the first of an eight part series on the Business Data Catalog (BDC).  While BDC is an enormously powerful tool, it’s also fairly complex and not well understood.  This series is considered technical in nature and intended for SharePoint installers, administrators or developers.  ]]></description>
			<content:encoded><![CDATA[<p>Welcome to the first of an eight part series on the Business Data Catalog (BDC).  While BDC is an enormously powerful tool, it’s also fairly complex and not well understood.  This series is considered technical in nature and intended for SharePoint installers, administrators or developers.  We’ll walk you through the BDC step-by-step, so no prior knowledge of BDC is expected, but you should already have a basic understanding of SharePoint.  For those that have some knowledge of BDC, this series will certainly will fill in the gaps to ensure you know everything you need to know.</p>
<p>We have three goals for this series:  1) Give you a strong understanding of what BDC is and how it works; 2) Ensure you recognize the value it brings organizations; 3) Provide you with the technical know-how to set it up and use its many features.</p>
<h4>BDC Overview</h4>
<p>As you already know, Microsoft Office SharePoint Server (MOSS) provides tremendous value as an intranet solution. One of the ways it excels is that it provides a single access point for the data assets in your organization. In many cases, these assets are stored in a Word doc, a PDF, an Excel workbook, etc.  In other words, it’s just a file. We call these sources unstructured data due to their flexibility in storing almost endless forms of information. It’s this flexibility that has made MS Office such a popular software suite. Users can work in a rich client application and then simply save the file, presumably into a document library.</p>
<p>This is where the power of MOSS as a document management system comes in. When coupled with an enterprise search engine, it’s even greater. Despite the unstructured nature of these files, users can go into their portal and by either a few navigation clicks or a quick search, they can find the answers they need. Having this centralized location for answers yields not only productive employees, but happy ones. It may seem that users have the best of both worlds: the flexibility of storing data the way they want, and the ability to publish it knowing that other users can find it.</p>
<p>But hang on, it’s not quite this easy. Sometimes, structure is necessary. Structure imposes rules and order. Do we really want to store all our customer orders in a single Excel sheet? Structure helps ensure we have valid, manageable, and most importantly, trusted data. For these structured data needs, IT professionals have relied on the tried and true relational database, and many vendors such as Oracle, IBM and Microsoft have made a bundle selling their flavor of SQL.</p>
<p>With these relational database management systems, information is locked in server-side databases. You usually work with the data through a separate application, perhaps a rich client or a web-based interface. These structured databases are the lifeblood for critical systems such as accounting, CRM (Customer Relationship Management), ERP (Enterprise Resource Planning), and a myriad of other line-of-business needs.</p>
<p>In fact, these solutions have become so popular and easy to build, they have sprung up all over the organization into what I like to call database sprawl. Typically, each of these systems is another data island, disconnected from the others. In many cases, information is duplicated across these systems, causing chaos where order was expected. From the user’s standpoint, they can be perceived as very inflexible and frustrating: Where is the data I need?  How do I log into that system?  Once I’m logged in, how do I access it?  By the time each question is answered, precious time is lost.  Or worse, we give up and make decisions based on no data at all.</p>
<p>This yields an interesting dichotomy in the way we store data. On one end, we have the unstructured nature of MS Office; on the other, we have the structure provided by the relational database. Interestingly, both can result in chaos. What you’ll be pleased to know is that MOSS can also bring some order to the database sprawl as well, and it does so in a very similar way. <img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image6.png" border="0" alt="image" width="290" height="190" align="right" /></p>
<p>With Business Data Catalog, part of MOSS Enterprise, we again get directed us back to the SharePoint interface to get access to our data. With BDC, this structured data can be exposed through Web Parts; it can be indexed and searched; it can be merged with data found in lists. With BDC connections to your back-end systems, we can find and consume both structured and unstructured data assets that exist in our organization. And we do this from one location, one interface.</p>
<h4>Architectural Overview</h4>
<p>A holistic view of what BDC can do and how it works is best depicted in Figure 1.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/11/image15.png"><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image-thumb9.png" border="0" alt="image" width="488" height="339" /></a><br />
<strong>Figure 1: BDC Architecture </strong></p>
<p>What you see along the top are the primary ways BDC can expose data from your back-end systems. Here is an overview of each of these from left to right:</p>
<p>1) BDC data can be surfaced using the many out-of-the-box Web Parts. This is the most common way and very easy for the users to search, filter and sort for information. You simply add one of the BDC Web Parts to any page, point it to one of the sources in the catalog and users are ready to go. All data is pulled in real-time using this approach.</p>
<p>2) SharePoint Lists allows you to merge data that lives in SharePoint along with data from a back-end system. For example, perhaps you have customer names stored within a list. From your CRM system, you would also like to see contact information for each customer. By adding a BDC field to your list, you can copy the corresponding data from your back-end system and store it within the list. Typically this matchup is done one-to-one. To ensure the copied data doesn’t get stale, users can refresh it on demand.</p>
<p>3) Search allows you to set up a content source and point it to an application in the BDC. SharePoint then goes through through BDC to crawl your structured data source and store the keywords in its index. Your search queries can now go across both structured and unstructured sources giving you a unified set of results.</p>
<p>4) User Profile Importer allows you to supplement attributes found in the User Profile store from external databases. This is important for many organizations as their Active Directory or LDAP directories are rarely populated with all user details. For example, how many IT administrators will actually fill in the birthday or skills attribute? Data like this is usually found in HR systems anyway.  Using BDC, these values can be pulled and matched up with the user, providing a complete set of accurate values.</p>
<p>5) With custom applications, you can avoid having to write another data layer for your new application. Instead of directly connecting to the system using ADO.NET or a Web Service, you can consume the data using the BDC Object Model. This gives you a more flexible, declarative style of talking to your back end.</p>
<p>With each of these approaches, you may have noticed that the concept is predominantly read-only in nature. This is similar to decision support systems.  That is, we usually use BDC to consume the data from these back end systems, but rarely write back to it. In the final article in this series, you’ll see how you can write to your back end system.</p>
<h4>A Quick Look at BDC in Action</h4>
<p>Let’s see how this works.  In this first example, we demonstrate the Business Data List Web Part (#1 from above).  This makes the finding and displaying of rows from a table very easy.  As you see here, we are finding all rows from the Customers table (perhaps from a CRM database) that contain the word “market” in the name.</p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image34.png" border="0" alt="image" width="719" height="224" /><br />
<strong>Figure 2: Business Data List Web Part</strong></p>
<p>In the second example, we see how users can search for both documents and BDC sources (#3 from above).  A search for Great Lakes has been issued, and we see both document and BDC Search Results listed together.  We’ll go into far more detail on these features and others as we get into other articles.</p>
<p><img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image1.png" border="0" alt="image" width="472" height="417" /><br />
<strong>Figure 3: BDC Search Results</strong></p>
<p><strong></strong></p>
<p><strong></strong></p>
<h4>How Does BDC Work</h4>
<p>Now that you have a better idea of what it can do, you’re probably wondering how does it work? As you can see, the BDC is a middle man between your interface and the back end. To provide this universal interface, it uses a database-like XML syntax that is called an Application Definition File or ADF. This ADF defines the connection, the entities (for a database, these are usually tables, views or stored procedures), how to filter, what associations <img src="http://sharepointmagazine.net/wp-content/uploads/2008/11/image5.png" border="0" alt="image" width="240" height="83" align="left" /> (relationships) exist and what user-friendly names should be used. These names can even be localized in different languages. This ADF is intended to be a generic interface describing the dictionary of information available. Once these ADF files are stored within the catalog, the first four options above are available without having to write any code. Of course, security is an important consideration when we talk about exposing sensitive data, so we’ll see how the BDC addresses this concern in the next article.</p>
<p>For the actual back end, as you can see in Figure 1 above, this can be any ADO.NET accessible database with an OLEDB or ODBC driver.  This covers most every database from MS Access and SQL Server to Oracle and IBM DB2. The back-end can also be a specially-written SOAP-based Web service.  The BDC is configured within a Shared Services Provider (SSP) which allows you to take advantage of BDC technology within any Web Applications within your SharePoint Farm.</p>
<h4>Series Outline</h4>
<p>With that, that nearly brings us to a close for this first article. But before we let you go, here is an outline on how we are structuring this series.  To get the full value, you should go through these in order, but we’ll try to keep them discrete so that you can jump around and focus on the ones that are most important to you. Note: these may slightly change as we go through each of these.</p>
<p><strong>Part 1</strong><strong><br />
</strong>In this first part, as you have now read, the focus is be on the concepts, the value it can bring organizations, the architecture, and an overview of each article in the series.</p>
<p><strong>Part 2</strong><strong><br />
</strong>This article will introduce the Application Definition File. By the end, you’ll understand the role it plays, how it works, and have a high-level grasp of its schema.  We’ll also introduce tools that allow you to generate these XML files.  Securing ADFs will also be covered in this article.</p>
<p><strong>Part 3</strong><strong><br />
</strong>This article will cover how the Web Services can be used instead of a direct connection to a database.  It will look at the kind of Web methods you’ll need to write if you want to expose your systems to BDC this way.</p>
<p><strong>Part 4</strong><strong><br />
</strong>This will be a two-part article.  In first half, we’ll look at the out of the box Web Parts that BDC provides.  These is the most common way that this structured data is presented to users, so we’ll give it a solid overview.  The second half will cover how you can cache BDC data into SharePoint lists.  This will allow you to marry SharePoint data and BDC together into one consolidated view.</p>
<p><strong>Part 5</strong><strong><br />
</strong>This article will cover everything you need to know to to configure Enterprise Search to crawl BDC data.  We’ll cover content sources, scopes, and how to configure MOSS for both full and incremental crawls of your structured data.</p>
<p><strong>Part 6</strong><strong><br />
</strong>As mentioned above, BDC can supplement properties contained within User Profiles. This allows you to pull critical data elements from external ERP or HR systems and map them to out-of-the-box or custom User Profile properties.  This article will cover everything you need to know to get this working for you.</p>
<p><strong>Part 7</strong><strong><br />
</strong>This article will apply mostly to the developers out there and will cover the BDC Object Model.  You’ll see how custom Web Parts, application pages or other custom-built SharePoint applications can consume BDC database without your having to write another data layer.</p>
<p><strong>Part 8</strong><strong><br />
</strong>In the final article, we will cover Custom Actions how these can be used to safely write changes to the back-end database or Web Service.  While not used often, this may prove to be a practical way for users to maintain some of the data in these external systems.</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Customizing Search Series &#8211; Creating the Custom Results Page</title>
		<link>http://sharepointmagazine.net/technical/development/customizing-search-series-created-the-custom-results-page</link>
		<comments>http://sharepointmagazine.net/technical/development/customizing-search-series-created-the-custom-results-page#comments</comments>
		<pubDate>Thu, 13 Nov 2008 08:58:50 +0000</pubDate>
		<dc:creator>stevemann</dc:creator>
				<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[box]]></category>
		<category><![CDATA[center]]></category>
		<category><![CDATA[customize]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[MOSS]]></category>
		<category><![CDATA[results]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[sharepoint]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=988</guid>
		<description><![CDATA[This is the fifth article within the Customizing Search Series. This article continues to build out the customization of search using a new content source based on the BDC. When we previously setup a custom scope, we left the target search page as the default. Now, we will create a new search results page for the client scope which will then be used to customize the actual rendering of the search results.]]></description>
			<content:encoded><![CDATA[<p>This is the fifth article within the Customizing Search Series. This article continues to build out the customization of search using a new content source based on the BDC. When we previously setup a custom scope, we left the target search page as the default. Now, we will create a new search results page for the client scope which will then be used to customize the actual rendering of the search results.</p>
<p><strong>Custom Search Page Creation</strong></p>
<p>The out-of-the-box Search Center actually contains both a Search Page and a Search Results page for All Sites and People. Therefore, to be consistent, we should also create a Search Page and Search Results Page for our new Clients scope.</p>
<p>First we will create the Search Page. Go to the Search Center site and select Create Page from the Site Actions menu:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-1.bmp"><img class="alignnone size-medium wp-image-990" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-1.bmp" alt="" /></a></p>
<p>On the Create Page screen enter Clients for the Title of the page and the URL name. Select the Search Page layout and then click on Create:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-2.bmp"><img class="alignnone size-medium wp-image-991" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-2.bmp" alt="" /></a></p>
<p>The new page will appear in Design mode. Edit the Search Box web part and enter &#8220;ClientResults.aspx&#8221; in the Target search results page URL setting (under Miscellaneous):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-3.bmp"><img class="alignnone size-medium wp-image-992" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-3.bmp" alt="" /></a></p>
<p>Click OK and Publish the page.</p>
<p><strong>Creating the Search Results Page</strong></p>
<p>The creation of the search results page is the same process. Go to the Search Center site and select Create Page from the Site Actions menu:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-4.bmp"><img class="alignnone size-medium wp-image-993" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-4.bmp" alt="" /></a></p>
<p>On the Create Page screen enter Client Results as the Title of the page and ClientResults for URL name. Select the Search Results Page layout and then click on Create:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-5.bmp"><img class="alignnone size-medium wp-image-994" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-5.bmp" alt="" /></a></p>
<p>The new page will appear in Design mode. Edit the Search Box web part and enter &#8220;ClientResults.aspx&#8221; in the Target search results page URL setting (under Miscellaneous):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-6.bmp"><img class="alignnone size-medium wp-image-995" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-6.bmp" alt="" /></a></p>
<p>Click OK and Publish the page.</p>
<p><strong> </strong></p>
<p><strong>Creating New Tabs</strong></p>
<p>Go back to the main Search Center again and Edit the Page. Click on Add Tab near the top:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-7-add-tab.bmp"><img class="alignnone size-medium wp-image-996" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-7-add-tab.bmp" alt="" /></a></p>
<p>This will bring up a screen to add a new tab (for Search Pages). Enter Clients for the tab name and Clients.aspx as the page (remember this is for the search pages, the results are next):</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-8.bmp"><img class="alignnone size-medium wp-image-997" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-8.bmp" alt="" /></a></p>
<p>Click Ok and publish the page.</p>
<p>Perform a search under the All Sites scope such that the results page appears. Edit this page and click on the Add New Tab towards the left of the screen:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-7-add-tab.bmp"><img class="alignnone size-medium wp-image-996" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-7-add-tab.bmp" alt="" /></a></p>
<p>This will bring up a screen to add a new tab again but this time it will be for the Search Results Pages. Enter Clients for the tab name and ClientResults.aspx as the page:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-10.bmp"><img class="alignnone size-medium wp-image-998" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-10.bmp" alt="" /></a></p>
<p>So now the Search Center should be loaded up with a Client Search Page, Client Search Results Page, and the appropriate tabs.</p>
<p><strong>Updating the Client Scope</strong></p>
<p>Now that we have the client results page created, we need to go back and update the scope such that any search within the client scope uses the proper results page. Therefore, back in Central Administration under the Search Settings, click on the View Scopes within the Scopes section:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-11.bmp"><img class="alignnone size-medium wp-image-999" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-11.bmp" alt="" /></a></p>
<p>On the next screen, select the Clients scope to bring up the scope properties and then click on the Change Scope Settings link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-12.bmp"><img class="alignnone size-medium wp-image-1000" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-12.bmp" alt="" /></a></p>
<p>This will bring up the Edit Scope screen. Simply change the Target Results Page setting to the &#8220;Specify a different page for searching this scope&#8221; and enter &#8220;ClientResults.aspx&#8221; within the Target results page box:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-13.bmp"><img class="alignnone size-medium wp-image-989" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/cr-13.bmp" alt="" /></a></p>
<p>Click OK. The scope will need to be updated but that happens automatically.</p>
<p><strong>What&#8217;s Next?</strong></p>
<p>We are coming down the home-stretch. Everything is now set-up for the customization of the search results. The final article will go into details in how we can use the managed properties and the results XSL to generate customized search results within our clients scope.</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/development/customizing-search-series-created-the-custom-results-page/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Customizing Search Series &#8211; Creating New Managed Properties</title>
		<link>http://sharepointmagazine.net/technical/customisation/customizing-search-series-creating-new-managed-properties-from-bdc-crawled-content</link>
		<comments>http://sharepointmagazine.net/technical/customisation/customizing-search-series-creating-new-managed-properties-from-bdc-crawled-content#comments</comments>
		<pubDate>Wed, 22 Oct 2008 07:46:17 +0000</pubDate>
		<dc:creator>stevemann</dc:creator>
				<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Crawled Content]]></category>
		<category><![CDATA[Managed Properties]]></category>
		<category><![CDATA[MOSS Search]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=970</guid>
		<description><![CDATA[Welcome to the fourth article in the customizing search series. This article, although one of the shorter ones, continues the journey in customizing search and builds upon the previous articles in this series.]]></description>
			<content:encoded><![CDATA[<p>Welcome to the fourth article in the customizing search series. This article, although one of the shorter ones, continues the journey in customizing search and builds upon the previous articles in this series.</p>
<p>Now that the BDC source has been created and crawled, managed properties must be mapped to the crawled properties such that those columns may be used within the search results (XSLT). The steps in this article need to be repeated for each data element that is to be used within the search results. For scenario purposes, a Client URL is being provided by the BDC and this is the link we want to show in the search results (versus the standard BDC properties page).</p>
<p>From the Configure Search Settings page and select the &#8220;Metadata property mappings&#8221; link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-1.bmp"><img class="alignnone size-medium wp-image-972" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-1.bmp" alt="" /></a></p>
<p>On the Metadata Property Mappings page click the New Managed Property button:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-2.bmp"><img class="alignnone size-medium wp-image-973" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-2.bmp" alt="" /></a></p>
<p>On the New Managed Property page, enter a name for the property, an applicable description, and select the type of information (most values will probably be the default of Text). After this has been entered, click on the Add Mapping button:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-3.bmp"><img class="alignnone size-medium wp-image-974" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-3.bmp" alt="" /></a></p>
<p>On the Crawled Property Mapping dialog, select the Business Data category. The list of available properties should appear. Find the appropriate property and select it. (If there are too many properties, enter a part of the name and use the Find button to narrow down the list).</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-4.bmp"><img class="alignnone size-medium wp-image-975" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-4.bmp" alt="" /></a></p>
<p>Click OK.  Back on the New Managed Property screen, select the &#8220;Allow this property to be used in scopes&#8221; checkbox and then click OK.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-5.bmp"><img class="alignnone size-medium wp-image-971" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/mp-5.bmp" alt="" /></a></p>
<p><strong><em>Repeat for the remaining BDC data elements. </em></strong></p>
<p><strong><em>A full crawl will be needed on the BDC content source once the managed properties have been added.</em></strong></p>
<p><strong>What&#8217;s Next?</strong></p>
<p>This was a short and sweet discussion but very necessary to continue. The next effort is to create the custom results page for use within the client search scope and therefore the next article will show the steps to successfully accomplish this task.</p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/customisation/customizing-search-series-creating-new-managed-properties-from-bdc-crawled-content/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Customizing Search Series &#8211; New Content and Scope from a BDC Application</title>
		<link>http://sharepointmagazine.net/technical/customisation/customizing-search-series-new-content-and-scope-from-a-bdc-application</link>
		<comments>http://sharepointmagazine.net/technical/customisation/customizing-search-series-new-content-and-scope-from-a-bdc-application#comments</comments>
		<pubDate>Tue, 23 Sep 2008 12:35:17 +0000</pubDate>
		<dc:creator>stevemann</dc:creator>
				<category><![CDATA[Customisation]]></category>
		<category><![CDATA[Technical]]></category>
		<category><![CDATA[BDC]]></category>
		<category><![CDATA[Content Source]]></category>
		<category><![CDATA[Customising Search]]></category>
		<category><![CDATA[Customizing Search]]></category>
		<category><![CDATA[MOSS Search]]></category>
		<category><![CDATA[Search Scope]]></category>

		<guid isPermaLink="false">http://sharepointmagazine.net/?p=837</guid>
		<description><![CDATA[This article builds upon the prior two discussions and begins to build out the customization scenario. The goal of this article is to build out a new search scope based on a content source from the Business Data Catalog (BDC).]]></description>
			<content:encoded><![CDATA[<p>Welcome to the third article in the Customizing Search Series. This article builds upon the prior two discussions and begins to build out the customization scenario. The goal of this article is to build out a new search scope based on a content source from the Business Data Catalog (BDC).</p>
<p>The out-of-the-box search features of MOSS 2007 include two scopes, All Sites and People; but what about customers or clients? Many organizations are in business because of their customer base; so when adding new scopes and search content, the customers are the next best bet (pun definitely intended).</p>
<p>Therefore this article will demonstrate the process of creating a Client scope for use in search from a BDC source. It assumes that a Client BDC definition file has been created and imported into the MOSS implementation. <em>The customer/client is simply a business scenario and the steps outlined can be used for any BDC application.</em></p>
<p><strong>Creating a Content Source for the Client BDC</strong></p>
<p>The first step is to add a content source to the search settings for the Client BDC. From Central Administration, select the SSP under the Shared Administrative Services menu. Select the Search Settings link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-1.bmp"><img class="alignnone size-medium wp-image-839" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-1.bmp" alt="" /></a></p>
<p>On the Configure Search Settings screen, select the &#8220;Content sources and crawl schedules&#8221; link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-2.bmp"><img class="alignnone size-medium wp-image-840" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-2.bmp" alt="" /></a></p>
<p>On the Manage Content Sources screen, select the New Content Source button:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-3.bmp"><img class="alignnone size-medium wp-image-841" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-3.bmp" alt="" /></a></p>
<p>The Add Content Source screen will appear. Enter a name for the content source and select Business Data as the type. The Applications section will refresh. Select the &#8220;Crawl selected applications&#8221; and make sure the instance checkbox is checked:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-4.bmp"><img class="alignnone size-medium wp-image-842" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-4.bmp" alt="" /></a></p>
<p>Enter the appropriate Full and Incremental Crawl schedules as applicable.</p>
<p><strong><em> </em></strong></p>
<p>At the bottom of the screen, select the &#8220;Start full crawl&#8230;&#8221; checkbox and then click OK:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-5.bmp"><img class="alignnone size-medium wp-image-843" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-5.bmp" alt="" /></a><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-4.bmp"></a></p>
<p>The Manage Content Sources screen should appear with the new content source entry:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-6.bmp"><img class="alignnone size-medium wp-image-844" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-6.bmp" alt="" /></a></p>
<p>Before proceeding, make sure the full crawl is completed and the status is Idle.</p>
<p><strong>Adding the Client Scope</strong></p>
<p>Return to the Configure Search Settings page and select the &#8220;View Scopes&#8221; link under the Scopes section:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-7.bmp"><img class="alignnone size-medium wp-image-845" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-7.bmp" alt="" /></a></p>
<p>On the View Scopes page, click on the New Scope button:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-8.bmp"><img class="alignnone size-medium wp-image-846" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-8.bmp" alt="" /></a></p>
<p>On the New Scopes page, enter a title for the scope. For now, make sure the &#8220;Use the default Search Results Page&#8221; is selected. We will generate a new search results page in future articles.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-9.bmp"><img class="alignnone size-medium wp-image-847" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-9.bmp" alt="" /></a></p>
<p>Click OK, the screen should return the View Scopes page. The new scope should be listed but with an Empty status. Click on the Add Rules link under this status:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-10.bmp"><img class="alignnone size-medium wp-image-848" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-10.bmp" alt="" /></a></p>
<p>On the Add Scope Rule page, select Content Source. This will make the Content Source section appear. Select the BDC content source created for the search previously. Leave the Behavior to the default &#8220;Include&#8221; and click OK:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-11.bmp"><img class="alignnone size-medium wp-image-849" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-11.bmp" alt="" /></a></p>
<p>Return to the Configure Search Settings screen and select the &#8220;Start update now&#8221; under the Scopes section:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-12.bmp"><img class="alignnone size-medium wp-image-850" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-12.bmp" alt="" /></a></p>
<p>The scope should begin the update process. Refreshing the screen will show the % complete on the Update status line. We are done with the SSP settings at this point.</p>
<p><strong>Adding the Scope to the Site Collection</strong></p>
<p>Open a new browser and navigate to the main MOSS web site. Select Site Settings from the Site Actions menus (if there is a extended menu, select &#8220;Modify All Site Settings&#8221;).</p>
<p>Under the Site Collection Administration section click on the Search Scopes link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-13.bmp"><img class="alignnone size-medium wp-image-851" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-13.bmp" alt="" /></a></p>
<p>On the View Scopes page, select the Search Dropdown link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-14.bmp"><img class="alignnone size-medium wp-image-852" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-14.bmp" alt="" /></a></p>
<p>On the Edit Scope Display Group screen, check the checkbox next to Clients scope. Click OK.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-15.bmp"><img class="alignnone size-medium wp-image-853" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-15.bmp" alt="" /></a></p>
<p>Back on the View Scopes page, select the Advanced Search link:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-16.bmp"><img class="alignnone size-medium wp-image-854" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-16.bmp" alt="" /></a></p>
<p>On the Edit Scope Display Group screen, check the checkbox next to Clients scope. Click OK.</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-17.bmp"><img class="alignnone size-medium wp-image-855" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-17.bmp" alt="" /></a></p>
<p>Navigate once again to the main MOSS site. The Clients scope should now appear in the search drop-down box:</p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-18.bmp"></a><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-18.bmp"></a></p>
<p><a href="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-181.bmp"><img class="alignnone size-medium wp-image-857" src="http://sharepointmagazine.net/wp-content/uploads/2008/09/content-181.bmp" alt="" /></a></p>
<p>Searching within this scope should yield results from the BDC.</p>
<p><strong>What&#8217;s Next?</strong></p>
<p>Now that the content source and scope has been created, in order to customize the search results, managed properties need to be mapped to the crawled content. The next article will explain the steps to create the managed properties.</p>
<p><strong> </strong></p>
<p><strong> </strong></p>
]]></content:encoded>
			<wfw:commentRss>http://sharepointmagazine.net/technical/customisation/customizing-search-series-new-content-and-scope-from-a-bdc-application/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
