Creating a SharePoint 2010 Web Part That Can Read and Write Data to an External Data Source

SharePoint Visual How To

Summary:  Learn how to use Microsoft Visual Studio 2010 to create a Visual Web Part that uses a Microsoft Business Connectivity Services (BCS) external content type in Microsoft SharePoint Server 2010 to read and write data to the AdventureWorks sample database.

Applies to: Business Connectivity Services | Office 2010 | SharePoint Foundation 2010 | SharePoint Server 2010 | Visual Studio | Visual Studio 2008 | Visual Studio 2010

Provided by:  Joel Krist, iSoftStone

Overview

Microsoft Business Connectivity Services (BCS) in SharePoint 2010 (BCS) is provided with Microsoft Office 2010 and SharePoint 2010. Building on the functionality of the Business Data Catalog in Microsoft Office SharePoint Server 2007, it introduces new features, such as external system write-back support and rich client integration. Visual Studio 2010 introduces the Visual Web Part project template. It enables you to use the Visual Web Part Designer to create SharePoint Web Parts and then package and deploy them as part of the build process. This Visual How To demonstrates how to use Visual Studio 2010 to create a Visual Web Part that uses the BCS object model to work with an external content type based on the AdventureWorks Customer entity.

Code It

This Visual How To contains the following sections to demonstrate how to create and use a Web Part that uses an external content type:

  • Prerequisites for using the Web Part

  • Using Visual Studio 2010 to create a Visual Web Part project

  • Adding references to the Visual Web Part project

  • Adding code to the Web Part to define its user interface and to add support for working with the external content type

  • Building the Web Part, deploying it to SharePoint Server, and using it on a Web Part page

Prerequisites for Using the Web Part

The Web Part that is demonstrated in this article works with a BCS external content type that is based on the Person.Contact, Sales.Customer, and Sales.Individual tables in the Microsoft SQL Server AdventureWorks sample database. The external content type is created in Microsoft SharePoint Designer 2010 and uses the AdventureWorks web service that is provided with the Microsoft SharePoint 2010 SDK.

This article focuses on how to create the Web Part. It does not describe in detail how to install the AdventureWorks sample database, deploy the AdventureWorks web service, or create the external content type in SharePoint Designer. Instead, it provides basic information about prerequisites and refers to other content for more information.

To use the Web Part that is described here, the following are required:

  • A server that is running Microsoft SQL Server 2005 or Microsoft SQL Server 2008.

  • The AdventureWorks 2005 online transaction processing (OLTP) database installed on the server that is running SQL Server. You can download the AdventureWorks sample databases from CodePlex.

  • A server that is running SharePoint Server 2010.

  • The sample AdventureWorks web service deployed on a web server. The web service is included with the Microsoft SharePoint 2010 SDK. By default, after you install the SDK, the AdventureWorks web service files are located in the following folder: C:\Program Files (x86)\Microsoft SDKs\SharePoint Server 2010\Samples\Business Connectivity Services\bcs sample kit\BCS Sample Kit\LOB Systems\Adventure Works Web Service.

  • Microsoft SharePoint Designer 2010 installed on the client computer.

  • The WSCustomer external content type based on the AdventureWorks web service. The article How to: Create an External Content Type Based on a Web Service provides step-by-step instructions for creating the WSCustomer external content type in SharePoint Designer 2010.

The information in the following sections assumes that you meet all these prerequisites.

Using Visual Studio 2010 to Create a Visual Web Part Project

The following procedure demonstrates how to create a Visual Web Part project.

To create a Visual Web Part project

  1. Start Visual Studio 2010 as an administrator.

  2. In Visual Studio, on the File menu, click New, and then click Project.

  3. In the New Project dialog box, in the Installed Templates pane, select the Visual C# SharePoint 2010 template type.

  4. In the templates list, select the Visual Web Part template.

  5. Name the project and solution CustomerWebPart, and then select .NET Framework 3.5 as the target framework version.

    Figure 1. Creating the solution

    Creating the solution
  6. Click OK.

    Visual Studio starts the SharePoint Customization Wizard. Enter the name of the local SharePoint site to use for debugging, and then click Finish.

    Figure 2. SharePoint Customization Wizard

    SharePoint customization wizard
  7. Visual Studio creates the solution and opens the VisualWebPart1UserControl.ascx user control in the Code Editor.

Adding References to the Visual Web Part Project

The following procedure demonstrates how to add references to the Visual Web Part project.

To add references to the Visual Web Part project

  1. The Web Part sample code that is provided with this article uses the classes and enumerations in the Microsoft.BusinessData namespace that is provided by the Microsoft.BusinessData.dll assembly. Add a reference to the Microsoft.BusinessData assembly, as follows:

    1. In Visual Studio, click Project, and then click Add Reference.

    2. In the Add Reference dialog box, on the Browse tab, navigate to the following folder: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI.

    3. Scroll down until the Microsoft.BusinessData.dll assembly is visible. Select the assembly, and then click OK.

      Figure 3. Add a reference to Microsoft.BusinessData

      Add a reference to Microsoft.BusinessData
  2. The sample code uses the Color class, which is defined in the System.Drawing assembly. Add a reference to the System.Drawing assembly:

    1. In Visual Studio, click Project, and then click Add Reference.

    2. In the Add Reference dialog box, on the .NET tab, scroll down until the System.Drawing component is visible, select the component, and then click OK.

      Figure 4. Add a reference to System.Drawing

      Add a reference to System.Drawing

Adding Code to the Web Part

The user interface of the Web Part is simple. It consists of a series of text boxes that enable you to enter and display the WSCustomer external content type fields, and buttons to perform Create, Find Item, and Update operations on the external content type.

    > [!NOTE]
    > <P>Because of table foreign key constraints, the sample AdventureWorks web service that is provided with the SharePoint 2010 SDK does not provide support for deleting customers from the AdventureWorks database. As a result, the Web Part in this article does not support deletion.</P>


  </div>
  <h3>To add code to the Web Part</h3>
  <div class="subSection">
    <ol>
      <li>
        <p>In Visual Studio, add the following markup to the VisualWebPart1UserControl.ascx file, after the default directives that were created by Visual Studio.</p>
        <pre class="xml">
          <code>&lt;style type="text/css"&gt;

.style3 { height: 81px; } .style4 { width: 119px; } .style5 { width: 559px; } .style6 { height: 81px; width: 119px; } .style7 { color : #FF3300; } </style>

<table> <tr> <td colspan="2"> To work with the AdventureWorks Customer External Content Type (ECT) enter values for the ECT name and namespace, then do the following:

  &lt;ul style="padding-left: 0px; margin-left: 14px"&gt;
    &lt;li&gt;To create a new customer, leave the customer ID blank,
        enter values in the other fields, and then select
        &lt;strong&gt;Create New&lt;/strong&gt;.
    &lt;/li&gt;
    &lt;li&gt;To find a specific customer, enter the customer&amp;#39;s ID
        and then select &lt;strong&gt;Find by ID&lt;/strong&gt;.
    &lt;/li&gt;
    &lt;li&gt;To update a customer, enter the customer&amp;#39;s ID and
        updated values for the other fields and then select
        &lt;strong&gt;Update&lt;/strong&gt;.
    &lt;/li&gt;   
  &lt;/ul&gt;
        
  &lt;asp:Label ID="StatusLabel" runat="server"
   ForeColor="#FF3300"&gt;&lt;/asp:Label&gt;
        
  &lt;br /&gt;
  &lt;br /&gt;
&lt;/td&gt;

</tr> <tr> <td align="left" class="style4"> ECT Name<span class="style7"></span></td> <td class="style5"> <asp:TextBox ID="ECTName" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> ECT Namespace<span class="style7"></span></td> <td class="style5"> <asp:TextBox ID="ECTNamespace" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4">&nbsp;</td> <td class="style5">&nbsp;</td> </tr> <tr> <td align="left" class="style4"> Customer ID</td> <td class="style5"> <asp:TextBox ID="CustomerID" runat="server"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> Title</td> <td class="style5"> <asp:TextBox ID="Title" runat="server"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> First Name</td> <td class="style5"> <asp:TextBox ID="FirstName" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> Middle Name</td> <td class="style5"> <asp:TextBox ID="MiddleName" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> Last Name</td> <td class="style5"> <asp:TextBox ID="LastName" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> Email</td> <td class="style5"> <asp:TextBox ID="Email" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="left" class="style4"> Phone</td> <td class="style5"> <asp:TextBox ID="Phone" runat="server" Width="100%"></asp:TextBox> </td> </tr> <tr> <td align="center" class="style6"> &nbsp; </td> <td align="center" class="style3"> <asp:Button ID="CreateNewCustomer" runat="server" OnClick="CreateNewCustomer_Click" Text="Create New" Width="120px" /> &nbsp; <asp:Button ID="FindCustomerByID" runat="server" OnClick="FindCustomerByID_Click" Text="Find by ID" Width="120px" /> &nbsp; <asp:Button ID="UpdateCustomer" runat="server" OnClick="UpdateCustomer_Click" Text="Update" Width="120px" /> &nbsp; <asp:Button ID="ClearAllFields" runat="server" onclick="ClearAllFields_Click" Text="Clear All Fields" Width="120px" /> </td> </tr> </table>

After you add this markup, when you view the VisualWebPart1UserControl.ascx user control in Design view, the user interface appears as shown in Figure 5.

Figure 5. User Control user interface

User control user interface
  • Right-click in the VisualWebPart1UserControl.ascx file, and then select View Code. The VisualWebPart1UserControl.ascx.cs file opens in the Visual Studio Code Editor.

  • Replace the contents of the VisualWebPart1UserControl.ascx.cs file with the following code.

    using System;
    using System.Drawing;
    using System.Web.UI;

    using Microsoft.SharePoint.BusinessData.SharedService; using Microsoft.BusinessData.MetadataModel; using Microsoft.BusinessData.Runtime; using Microsoft.SharePoint.Administration; using Microsoft.SharePoint;

    using Microsoft.BusinessData.Infrastructure; using Microsoft.BusinessData.MetadataModel.Collections;

    namespace CustomerWebPart.VisualWebPart1 { public partial class VisualWebPart1UserControl : UserControl { #region Properties

    protected string EntityNamespace
    {
      get { return ECTNamespace.Text.Trim(); }
    }
    
    protected string EntityName
    {
      get { return ECTName.Text.Trim(); }
    }
    
    protected bool EntityValuesAreSet
    {
      get
      {
        if (EntityNamespace == string.Empty ||
          EntityName == string.Empty)
          return false;
        else
          return true;
      }
    }
    
    #endregion
    
    protected void Page_Load(object sender, EventArgs e)
    {
    }
    
    #region Create Customer
    
    protected void CreateNewCustomer_Click(object sender,
      EventArgs e)
    {
      // Ensure that we have values for the entity namespace and name.
      if (!EntityValuesAreSet)
      {
        DisplaySetPropertyValuePrompt(true);
        return;
      }
      else
        DisplaySetPropertyValuePrompt(false);
    
      try
      {
        using (new Microsoft.SharePoint.SPServiceContextScope(
          SPServiceContext.GetContext(SPContext.Current.Site)))
        {
          // Get the BDC service and metadata catalog.
          BdcService service =
           SPFarm.Local.Services.GetValue&lt;BdcService&gt;(String.Empty);
          IMetadataCatalog catalog =
            service.GetDatabaseBackedMetadataCatalog(
            SPServiceContext.Current);
    
          // Get the entity by using the specified name and namespace.
          IEntity entity =
            catalog.GetEntity(EntityNamespace, EntityName);
          ILobSystemInstance LobSysteminstance =
            entity.GetLobSystem().GetLobSystemInstances()[0].Value;
    
          // Get the fields on the entity.
          IView createView =
            entity.GetCreatorView("CreateCustomer");
          IFieldValueDictionary valueDictionary =
            createView.GetDefaultValues();
    
          // Set the values of the entity fields.
          valueDictionary["EmailAddress"] = Email.Text;
          valueDictionary["FirstName"] = FirstName.Text;
          valueDictionary["LastName"] = LastName.Text;
          valueDictionary["MiddleName"] = MiddleName.Text;
          valueDictionary["Phone"] = Phone.Text;
          valueDictionary["Title"] = Title.Text;
    
          // Call the creator method and display the returned
          // Customer ID.
          Identity id = entity.Create(valueDictionary,
            LobSysteminstance);
    
          CustomerID.Text =
            id.GetIdentifierValues().GetValue(0).ToString();
    
          StatusLabel.ForeColor = Color.Green;
          StatusLabel.Text = "Customer successfully created.";
        }
      }
      catch (Exception ex)
      {
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text = "Unable to create customer." +
          ex.Message;
      }
    }
    
    #endregion
    
    #region Find Customer By ID
    
    protected void FindCustomerByID_Click(
      object sender, EventArgs e)
    {
      // Ensure that we have values for the entity namespace and name.
      if (!EntityValuesAreSet)
      {
        DisplaySetPropertyValuePrompt(true);
        return;
      }
      else
        DisplaySetPropertyValuePrompt(false);
    
      // Do simple validation of the customer ID. Ensure that it is
      // an integer.  
      int customerID = -1;
    
      if (!ValidateCustomerID(CustomerID.Text, ref customerID))
      {
        ClearFields(false);
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text =
          "Please enter an integer for the Customer ID value.";
        return;
      }
    
      try
      {
        using (new Microsoft.SharePoint.SPServiceContextScope(
          SPServiceContext.GetContext(SPContext.Current.Site)))
        {
          // Get the BDC service and metadata catalog.
          BdcService service =
           SPFarm.Local.Services.GetValue&lt;BdcService&gt;(String.Empty);
          IMetadataCatalog catalog =
            service.GetDatabaseBackedMetadataCatalog(
            SPServiceContext.Current);
    
          // Get the entity by using the specified name and namespace.
          IEntity entity =
            catalog.GetEntity(EntityNamespace, EntityName);
          ILobSystemInstance LobSysteminstance =
            entity.GetLobSystem().GetLobSystemInstances()[0].Value;
    
          // Create an Identity based on the specified Customer ID.
          Identity identity = new Identity(customerID);
    
          // Get a method instance for the SpecificFinder method.
          IMethodInstance method =
            entity.GetMethodInstance("GetCustomerById",
            MethodInstanceType.SpecificFinder);
    
          // Execute the Specific Finder method to return the
          // customer data.
          IEntityInstance iei =
            entity.FindSpecific(identity, LobSysteminstance);
    
          // Display the data for the returned customer in the UI.
          Title.Text = iei["Title"] != null ?
            iei["Title"].ToString() : string.Empty;
          FirstName.Text = iei["FirstName"] != null ?
            iei["FirstName"].ToString() : string.Empty;
          MiddleName.Text = iei["MiddleName"] != null ?
            iei["MiddleName"].ToString() : string.Empty;
          LastName.Text = iei["LastName"] != null ?
            iei["LastName"].ToString() : string.Empty;
          Email.Text = iei["EmailAddress"] != null ?
            iei["EmailAddress"].ToString() : string.Empty;
          Phone.Text = iei["Phone"] != null ?
            iei["Phone"].ToString() : string.Empty;
        }
      }
      catch (Exception ex)
      {
        ClearFields(false);
    
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text = "Unable to find customer with ID = " +
          CustomerID.Text + ". " + ex.Message;
      }
    }
    
    #endregion
    
    #region Update Customer
    
    protected void UpdateCustomer_Click(object sender, EventArgs e)
    {
      // Ensure that we have values for the entity namespace and name.
      if (!EntityValuesAreSet)
      {
        DisplaySetPropertyValuePrompt(true);
        return;
      }
      else
        DisplaySetPropertyValuePrompt(false);
    
      // Do simple validation of the customer ID. Ensure that it is
      // an integer.     
      int customerID = -1;
    
      if (!ValidateCustomerID(CustomerID.Text, ref customerID))
      {
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text =
          "Please enter an integer for the Customer ID value.";
        return;
      }
    
      try
      {
        using (new Microsoft.SharePoint.SPServiceContextScope(
          SPServiceContext.GetContext(SPContext.Current.Site)))
        {
          // Get the BDC service and metadata catalog.
          BdcService service =
           SPFarm.Local.Services.GetValue&lt;BdcService&gt;(String.Empty);
          IMetadataCatalog catalog =
            service.GetDatabaseBackedMetadataCatalog(
            SPServiceContext.Current);
    
          // Get the entity by using the specified name and namespace.
          IEntity entity =
            catalog.GetEntity(EntityNamespace, EntityName);
          ILobSystemInstance LobSysteminstance =
            entity.GetLobSystem().GetLobSystemInstances()[0].Value;
          
          // Create an Identity based on the specified Customer ID.
          Identity identity = new Identity(customerID);
    
          // Get a method instance for the Updater method.
          IMethodInstance method =
            entity.GetMethodInstance("UpdateCustomer",
            MethodInstanceType.Updater);
    
          // The UpdateCustomer method of the external content type
          // maps to the UpdateCustomer method in the AdventureWorks
          // web service. Looking at the source for the web service
          // shows that the UpdateCustomer method has the following
          // signature:
          //
          // public void UpdateCustomer(SalesCustomer customer)
          //
          // The SalesCustomer type has the following layout: 
          //
          // public class SalesCustomer
          // {
          //     public int CustomerId { get; set; }
          //     public String Title { get; set; }
          //     public String FirstName { get; set; }
          //     public String MiddleName { get; set; }
          //     public String LastName   { get; set; }
          //     public String EmailAddress { get; set; }
          //     public String Phone { get; set; }
          //     public DateTime ModifiedDate { get; set; }
          // }
    
          // Get the collection of parameters for the method.
          // In this case, there is only one.
          IParameterCollection parameters =
            method.GetMethod().GetParameters();
    
          // Use type reflection to get an instance of a
          // SalesCustomer object to pass as a parameter.
          ITypeReflector reflector = parameters[0].TypeReflector;
          ITypeDescriptor rootTypeDescriptor =
            parameters[0].GetRootTypeDescriptor();
    
          object[] methodParamInstances =
            method.GetMethod().CreateDefaultParameterInstances(
            method);
          Object instance = methodParamInstances[0];
    
          // Get type descriptors for each of the SalesCustomer
          // members.
          ITypeDescriptor customerIDTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[0];
          ITypeDescriptor titleTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[1];
          ITypeDescriptor firstNameTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[2];
          ITypeDescriptor middleNameTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[3];
          ITypeDescriptor lastNameTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[4];
          ITypeDescriptor emailAddressTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[5];
          ITypeDescriptor phoneTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[6];
          ITypeDescriptor modifiedDateTypeDescriptor =
            rootTypeDescriptor.GetChildTypeDescriptors()[7];
    
          // Set the values of the SalesCustomer object members
          // with the values specified by the user.
          reflector.Set(customerIDTypeDescriptor,
            rootTypeDescriptor,
            ref instance, customerID);
          reflector.Set(titleTypeDescriptor, rootTypeDescriptor,
            ref instance, Title.Text);
          reflector.Set(firstNameTypeDescriptor, rootTypeDescriptor,
            ref instance, FirstName.Text);
          reflector.Set(middleNameTypeDescriptor,
            rootTypeDescriptor,
            ref instance, MiddleName.Text);
          reflector.Set(lastNameTypeDescriptor, rootTypeDescriptor,
            ref instance, LastName.Text);
          reflector.Set(emailAddressTypeDescriptor,
            rootTypeDescriptor,
            ref instance, Email.Text);
          reflector.Set(phoneTypeDescriptor, rootTypeDescriptor,
            ref instance, Phone.Text);
          reflector.Set(modifiedDateTypeDescriptor,
            rootTypeDescriptor,
            ref instance, DateTime.Now);
    
          // Execute the updater method, passing the parameter.
          entity.Execute(method, LobSysteminstance,
            ref methodParamInstances);
    
          StatusLabel.ForeColor = Color.Green;
          StatusLabel.Text = "Customer successfully updated.";
        }
      }
      catch (Exception ex)
      {
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text = "Unable to find customer with ID = " +
          CustomerID.Text + ". " + ex.Message;
      }
    }
    
    #endregion
    
    #region Helpers
    
    protected void DisplaySetPropertyValuePrompt(bool showPrompt)
    {
      if (showPrompt)
      {
        StatusLabel.ForeColor = Color.Red;
        StatusLabel.Text =
          "Please enter values for the ECT name and namespace!";
      }
      else
        StatusLabel.Text = string.Empty;
    }
    
    protected void ClearAllFields_Click(object sender, EventArgs e)
    {
      ClearFields(true);
    }
    
    protected bool ValidateCustomerID(string CustomerIDIn,
      ref int CustomerIDOut)
    {
      try
      {
        CustomerIDOut = Convert.ToInt32(CustomerIDIn);
        return true;
      }
      catch
      {
        CustomerIDOut = -1;
        return false;
      }
    }
    
    protected void ClearFields(bool clearCustomerID)
    {
      if (clearCustomerID)
        CustomerID.Text = string.Empty;
    
      Title.Text = string.Empty;
      FirstName.Text = string.Empty;
      MiddleName.Text = string.Empty;
      LastName.Text = string.Empty;
      Email.Text = string.Empty;
      Phone.Text = string.Empty;
    }
    
    #endregion
    

    } }

  • Building, Deploying, and Using the Web Part

    The following procedure demonstrates how to build, deploy, and use the Web Part.

    To build, deploy, and use the Web Part

    1. In Visual Studio, on the Build menu, click Deploy Solution.

      Visual Studio builds the Web Part assembly, creates the required feature and deployment files, packages everything into a SharePoint solution package, and deploys it to the local SharePoint site that you specified when you created the solution.

      Figure 6. Building and deploying the Web Part

      Building and deploying the web part
    2. Browse to the SharePoint site that you deployed the Web Part to.

    3. On the Site Actions menu, click New Page.

      Figure 7. New Page dialog box

      New Page dialog box
    4. In the New Page dialog box, type a name for the new page, and then click Create. SharePoint Server creates the new page and navigates to it.

    5. On the new page, on the Insert tab, in the Web Parts group, click Web Part.

      Figure 8. Adding the Web Part to the page

      Adding the web part to the page
    6. SharePoint Server displays the user interface that you can use to select the Web Part. Under Categories, select Custom. The Visual Web Part appears in the list of available Web Parts. Select the Web Part, and then click Add.

      Figure 9. Selecting the Web Part

      Selecting the web part

      The Web Part is added to the page.

      Figure 10. Web Part on the page

      Web part on the page
    7. Save the changes to the page by clicking the Save icon above the ribbon.

    8. Enter values for the external content type name and namespace.

      If you followed the steps in How to: Create an External Content Type Based on a Web Service exactly, the external content type name is WSCustomer, and the namespace is based on the name of the web server that is hosting the AdventureWorks web service. To determine the external content type name and namespace, follow these steps:

      1. Open the SharePoint Central Administration site on the server that you deployed the external content type to by using SharePoint Designer.

      2. Select Application Management.

      3. On the Application Management page, select Manage service applications.

      4. On the Service Applications page, select the link for the Business Data Connectivity Service Application.

        The Service Application Information page appears. The details of the AdventureWorks WSCustomer external content type are listed.

        Figure 11. External content type details

        External content type details
    9. In the Web Part user interface, enter a valid value for the Customer ID. You can determine valid customer IDs by using a tool such as SQL Server Management Studio to query the Sales.Individual table in the AdventureWorks database.

    10. Click Find by ID.

      The Web Part displays the data for the customer who has the specified ID. It is retrieved from the AdventureWorks database via the external content type by using the AdventureWorks web service.

      Figure 12. Web Part displaying AdventureWorks customer data

      Web part displaying AdventureWorks
    11. Modify the data for the customer, leaving the Customer ID unchanged, and then click Update. The Web Part uses the external content type to update the customer data.

      Figure 13. Updating customer data

      Updating customer data
    12. Create a new customer by clicking Clear All Fields and then entering data for a new customer, leaving the Customer ID field blank. Click Create New, and the Web Part uses the external content type to add a new customer to the AdventureWorks database.

      Figure 14. Creating a new Customer

      Creating new customer

      You can use SQL Server Management Studio to query the AdventureWorks database to verify that the Web Part operations via the external content type are working correctly.

      Figure 15. SQL Server Management Studio

      SQL Server Management Studio
    Read It

    This Visual How To provides steps and sample code that demonstrate how to use Visual Studio 2010 to create a Visual Web Part that uses a BCS external content type to read and write data to the AdventureWorks database. The sample code shows how to use the Create, Specific Finder, and Update methods of the external content type, which is based on the sample AdventureWorks web service that is provided with the SharePoint 2010 SDK.

    Each method in the Web Part uses the same approach to get references to the BDC Shared Service and the metadata catalog on the server and to retrieve the customer entity from the catalog.

    // Get the BDC service and metadata catalog.
    BdcService service =
    SPFarm.Local.Services.GetValue<BdcService>(String.Empty);
    IMetadataCatalog catalog = service.GetDatabaseBackedMetadataCatalog(
    SPServiceContext.Current);

    // Get the entity by using the specified name and namespace. IEntity entity = catalog.GetEntity(EntityNamespace, EntityName); ILobSystemInstance LobSysteminstance = entity.GetLobSystem().GetLobSystemInstances()[0].Value;

    The methods then take different approaches to implement their functionality. The create-related code gets a view on the CreateCustomer method of the external content type, so that it can get and set the entity fields, which are then passed to the entity's creator method.

    // Get the fields on the entity.
    IView createView = entity.GetCreatorView("CreateCustomer");
    IFieldValueDictionary valueDictionary =
    createView.GetDefaultValues();

    // Set the values of the entity fields. valueDictionary["EmailAddress"] = Email.Text; valueDictionary["FirstName"] = FirstName.Text; valueDictionary["LastName"] = LastName.Text; valueDictionary["MiddleName"] = MiddleName.Text; valueDictionary["Phone"] = Phone.Text; valueDictionary["Title"] = Title.Text;

    // Call the creator method and display the returned // Customer ID. Identity id = entity.Create(valueDictionary, LobSysteminstance);

    The specific finder–related code creates an Identity object and then gets a method instance on the Specific Finder method of the external content type. It then calls the FindSpecific method on the entity, which returns an IEntityInstance object that contains the data for the specified customer.

    // Create an Identity based on the specified Customer ID.
    Identity identity = new Identity(customerID);

    // Get a method instance for the SpecificFinder method. IMethodInstance method = entity.GetMethodInstance("GetCustomerById", MethodInstanceType.SpecificFinder);

    // Execute the Specific Finder method to return the // customer data. IEntityInstance iei = entity.FindSpecific(identity, LobSysteminstance);

    The update-related code creates an Identity object and then gets a method instance on the Updater method of the external content type. It uses the method instance to get the collection of parameters that are accepted by the Updater method and then uses type reflection to create and initialize an instance of the object to pass to the method. Finally, it calls IEntity.Execute to call the Updater method of the external content type, passing the parameter with the updated values for the customer.

    // Create an Identity based on the specified Customer ID.
    Identity identity = new Identity(customerID);

    // Get a method instance for the Updater method. IMethodInstance method = entity.GetMethodInstance("UpdateCustomer", MethodInstanceType.Updater);

    // Get the collection of parameters for the method. // In this case, there is only one. IParameterCollection parameters = method.GetMethod().GetParameters();

    // Use type reflection to get an instance of a // SalesCustomer object to pass as a parameter. ITypeReflector reflector = parameters[0].TypeReflector; ITypeDescriptor rootTypeDescriptor = parameters[0].GetRootTypeDescriptor();

    object[] methodParamInstances = method.GetMethod().CreateDefaultParameterInstances( method); Object instance = methodParamInstances[0];

    // Get type descriptors for each of the SalesCustomer // members. ITypeDescriptor customerIDTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[0]; ITypeDescriptor titleTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[1]; ITypeDescriptor firstNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[2]; ITypeDescriptor middleNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[3]; ITypeDescriptor lastNameTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[4]; ITypeDescriptor emailAddressTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[5]; ITypeDescriptor phoneTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[6]; ITypeDescriptor modifiedDateTypeDescriptor = rootTypeDescriptor.GetChildTypeDescriptors()[7];

    // Set the values of the SalesCustomer object members // with the values specified by the user. reflector.Set(customerIDTypeDescriptor, rootTypeDescriptor, ref instance, customerID); reflector.Set(titleTypeDescriptor, rootTypeDescriptor, ref instance, Title.Text); reflector.Set(firstNameTypeDescriptor, rootTypeDescriptor, ref instance, FirstName.Text); reflector.Set(middleNameTypeDescriptor, rootTypeDescriptor, ref instance, MiddleName.Text); reflector.Set(lastNameTypeDescriptor, rootTypeDescriptor, ref instance, LastName.Text); reflector.Set(emailAddressTypeDescriptor, rootTypeDescriptor, ref instance, Email.Text); reflector.Set(phoneTypeDescriptor, rootTypeDescriptor, ref instance, Phone.Text); reflector.Set(modifiedDateTypeDescriptor, rootTypeDescriptor, ref instance, DateTime.Now);

    // Execute the updater method, passing the parameter. entity.Execute(method, LobSysteminstance, ref methodParamInstances);

    See It

    Watch the video

    Watch video

    Length: 00:15:57

    Click to grab code

    Grab the Code

    Explore It