Tuesday, October 21, 2008

Programmatically set a BDC column

********** UPDATE **********

I've created a new post as a follow up to this article. It contains C# code for a class I created to work with business data in SharePoint 2007. There is a public method in there called "SetFieldByID" which will set the value of a BDC column including all auxiliary fields.

Click here to view the post.

*****************************


Finally!

I spent way too much time playing around with this one... There is no documentation, and very little discussion about it in the forums. All I wanted to do was be able to set the value(s) of a Business Data Catalog field programatically through the SharePoint object model.

Sounds simple enough right?

Not quite....

The first thing to note is that you can't just set the value of the column like you would do with other fields like so:

mySPListItem["myBDCField"] = 123;

If you do this, you won't get an error, but the value will not be set...

This reference was a useful start: http://www.portalsolutions.net/Blog/Lists/Posts/Post.aspx?ID=18. However, I still encountered some challenges in setting a BDC column value.

First of all, the EntityInstanceIdEncoder class is found in the following namespace:
Microsoft.Office.Server.ApplicationRegistry.Infrastructure;
The referenced dll is found in the ISAPI folder on the SharePoint server:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

Now for some code...

To check if a field is a BDC field:

if(spItem.Fields["SomeField"].TypeAsString == "BusinessData")


To get the BDC field:
SPField bdcField = spItem.Fields[sBDCColumnName];

To get the BDC column entity internal name (this is key):
XmlDocument xmlData = new XmlDocument();
xmlData.LoadXml(bdcField.SchemaXml);
String sEntityName = xmlData.FirstChild.Attributes["RelatedFieldWssStaticName"].Value;

Set the primary key of the BDC field:
spItem[sEntityName] = EntityInstanceIdEncoder.EncodeEntityInstanceId(new object[] { Value }); - Here you may want to add some logic to cast the the passed value to the proper type.

Set the display value of the column:
spItem[sBDCColumnName] = Value;

You also need to explicitly set the values of any of the additional related fields. These values can be set like any other column:

spItem[ BDCFieldName + ": " + BDCDisplayFieldName ] = "SomeValue";

// ex: spItem["Products: Name"] = "XYZ";

Hope this saves somebody the trouble that I went through to figure this out!