to represent the Customers table and define which column(s) make up the identifier for the
.
, specify the query it will use, and define the input and output parameters associated with it. The specific finder
returns exactly one row of data from the data source, given an identifier.
//Create the specific finder method
Method getCustomerMethod = customerEntity.Methods.Create("GetCustomer", true, false, "GetCustomer");
//Specify the query
getCustomerMethod.Properties.Add("RdbCommandText", "SELECT [CustomerId] ,
[FirstName] , [LastName] , [Phone] , [EmailAddress] , [CompanyName]
FROM[Customers].[SalesLT].[Customer]
WHERE [CustomerId] = @CustomerId");
//Set the command type
getCustomerMethod.Properties.Add("RdbCommandType", "Text");
//Create the CustomerID input parameter
Parameter customerIDParameter =
getCustomerMethod.Parameters.Create("@CustomerId", true, DirectionType.In);
//Create the TypeDescriptor for the CustomerID parameter
customerIDParameter.CreateRootTypeDescriptor("CustomerId", true, "System.Int32",
"CustomerId", new IdentifierReference("CustomerId",
new EntityReference("AdventureWorks", "Customer", catalog), catalog),
null, TypeDescriptorFlags.None, null, catalog);
//Create the Customer return parameter
Parameter customerParameter =
getCustomerMethod.Parameters.Create("Customer", true, DirectionType.Return);
//Create the TypeDescriptors for the Customer return parameter
TypeDescriptor returnRootCollectionTypeDescriptor =
customerParameter.CreateRootTypeDescriptor( "Customers", true,
"System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089", "Customers", null, null,
TypeDescriptorFlags.IsCollection, null, catalog);
TypeDescriptor returnRootElementTypeDescriptor =
returnRootCollectionTypeDescriptor.ChildTypeDescriptors.Create( "Customer", true,
"System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089",
"Customer", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "CustomerId", true,
"System.Int32", "CustomerId", new IdentifierReference("CustomerId",
new EntityReference("AdventureWorks", "Customer", catalog),
catalog), null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "FirstName", true,
"System.String", "FirstName",
null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "LastName", true,
"System.String", "LastName",
null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "Phone", true,
"System.String", "Phone", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "EmailAddress", true,
"System.String", "EmailAddress", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor.ChildTypeDescriptors.Create( "CompanyName", true,
"System.String", "CompanyName", null, null, TypeDescriptorFlags.None, null);
//Create the specific finder method instance
getCustomerMethod.MethodInstances.Create("GetCustomer", true,
returnRootElementTypeDescriptor, MethodInstanceType.SpecificFinder, true);
Define the Finder Method, Parameters and Type Descriptors
Next, create the finder
Method, specify the query it will use, and define the output parameters associated with it. The finder
Method returns all of the rows of data from the data source which its query defines.
//Create the Finder method
Method getCustomersMethod = customerEntity.Methods.Create("GetCustomers", true,
false, "GetCustomers");
//Specify the query
getCustomersMethod.Properties.Add("RdbCommandText", "SELECT [CustomerId] ,
[FirstName] , [LastName] , [Phone] , [EmailAddress] , [CompanyName]
FROM [Customers].[SalesLT].[Customer]");
//Set the command type
getCustomersMethod.Properties.Add("RdbCommandType", "Text");
//Create the Customer return parameter
Parameter customersParameter = getCustomersMethod.Parameters.Create("Customer", true,
DirectionType.Return);
//Create the TypeDescriptors for the Customer return parameter
TypeDescriptor returnRootCollectionTypeDescriptor2 =
customersParameter.CreateRootTypeDescriptor("Customers", true,
"System.Data.IDataReader, System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089", "Customers", null, null,
TypeDescriptorFlags.IsCollection, null, catalog);
TypeDescriptor returnRootElementTypeDescriptor2 =
returnRootCollectionTypeDescriptor2.ChildTypeDescriptors.Create( "Customer", true,
"System.Data.IDataRecord, System.Data, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089", "Customer", null, null,
TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "CustomerId", true,
"System.Int32", "CustomerId", new IdentifierReference("CustomerId",
new EntityReference("AdventureWorks", "Customer", catalog), catalog),
null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "FirstName", true,
"System.String", "FirstName", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "LastName", true,
"System.String", "LastName", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "Phone", true,
"System.String", "Phone", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "EmailAddress", true,
"System.String", "EmailAddress", null, null, TypeDescriptorFlags.None, null);
returnRootElementTypeDescriptor2.ChildTypeDescriptors.Create( "CompanyName", true,
"System.String", "CompanyName", null, null, TypeDescriptorFlags.None, null);
getCustomersMethod.MethodInstances.Create("GetCustomers", true,
returnRootCollectionTypeDescriptor2, MethodInstanceType.Finder, true);
Commit the changes
Finally, commit the changes to the BCS Metadata Store.
//Publish the Customer Entity
customerEntity.Activate();
Verification
After the code executes check Central Administration to verify the external content type is successfully created. Then create an external list to verify the external content type works as expected.
Central Administration
To verify the external content type is successfully created follow these steps.
- Open SharePoint Central Administration
- Click Application Management
- Click Manage service applications
- Click the Business Data Connectivity service
- In the ribbon, click Manage
- In the ribbon, click Edit
- Select BDC Models in the View dropdown list
- Verify the BDC Model is in the list

- In the ribbon, click Edit
- Select External Content Types in the View dropdown list
- Verify the BCS Model is in the list
Create An External List
To verify the external content type works as expected follow these steps.
- Open the SharePoint web site where you created the external content type
- Log in as a user who has the permission to create lists
- Click the Site Actions menu
- Select View All Site Content
- Click Create
- In the Filter By section, click List
- Select External List

- Click the Create button
- In the Name textbox enter Programmatically Generated External Content Type
- Click the button to browse the external content types

- Select the Customer External Content Type in the External Content Type Picker

- Click OK
- Click Create
- View the data from the data source in the external list

Wrap Up
As always, I hope this article saves you time and effort and helps you understand how to put this technology to use. There are several good BCS articles appearing on the Internet lately. You may check them out at the following blogs.
BCS Team Blog
Nick Swan’s blog
Fabian Williams’ blog
Yeah baby, only 12 days and I’m on vacation in Mexico!!!