Question

I cannot seem to find any examples of how to set a BCS External Field via code. I have two lists that both have a BCS field named "Industry". When an item is created in List A I need to create a new item in B and set the value of the industry field to be the same as the value in the new item in list A.

Using ParseAndSetValue only works on the field when it has an initial value. Meaning when the item in list A is created with a value of "Paving" the item in list B is blank even though the code to set it executes. When I update the item in list A and change the value to "Agriculture" again nothing happens (though the code does execute). If I manually set the item in list B to "Paving" and then change the item in list A to "Agriculture" the item in list B is updated to "Agriculture". Here is my example code for said change. This is running in ItemUpdating, the code running in ItemAdded is basically the same.

if (industryChanged)
{
    using (new DisabledItemEventsScope())
    {
       String new_value = properties.AfterProperties[MarketNeedFieldNames.Industry_Internal].ToString();
       SPBusinessDataField ind = item.Fields[MarketNeedFieldNames.Industry_Internal] as SPBusinessDataField;
        ind.ParseAndSetValue(item, new_value);
        item.SystemUpdate();
     }
}

Update:

If I go through each item in the list using PowerShell I DO see values for the field in list B but not via the SharePoint UI. The ones with a value visible in the SharePoint UI were all updated via the item picker.

$web = Get-SPWeb "http://dom-dev.domain.net/sites/plm"
$mnlist = $web.Lists["MarketNeed_Priority"]

foreach($item in $mnlist.Items)
{
    $item["Industry"] + " - " + $item["Request_ID"]
}
  • Earthmoving Excavating - NONE-00001
  • Terrain - NONE-00002
  • Paving - XXX-00001
  • Compact Machine Solutions - NONE-00003
  • Paving - NONE-00004
  • Compact Machine Solutions - NONE-00005
  • Earthmoving Grading - NONE-00006

enter image description here

Was it helpful?

Solution

Hope following article will helps,

http://rompenpatrick.wordpress.com/2012/07/19/programmatically-setting-bcs-external-data-column/

When you create a BCS based, external data column within a SharePoint list there is another, hidden field created for you. This is given the name yourFieldName_ID so that if your field is called "Industry" the hidden field is called Industry_ID. This holds the BCS entity id for the entity in question. The name of this field is also stored within the SchemaXml property of the BusinessData field. You can set it my using this extension method:

    /// <summary>
    /// Sets the value of an SPBusinessDataField to the newValue.
    /// </summary>
    /// <param name="item"></param>
    /// <param name="fieldInternalName"></param>
    /// <param name="newValue"></param>
    public static void SetExternalFieldValue(this SPListItem item, string fieldInternalName, string newValue)
    {
        if (item.Fields[fieldInternalName].TypeAsString == "BusinessData")
        {
            SPField myField = item.Fields[fieldInternalName];
            XmlDocument xmlData = new XmlDocument();
            xmlData.LoadXml(myField.SchemaXml);
            //Get teh internal name of the SPBusinessDataField's identity column.
            String entityName = xmlData.FirstChild.Attributes["RelatedFieldWssStaticName"].Value;

            //Set the value of the identity column.
            item[entityName] = EntityInstanceIdEncoder.EncodeEntityInstanceId(new object[] { newValue });
            item[fieldInternalName] = newValue;
        }
        else
        {
            throw new InvalidOperationException(fieldInternalName + " is not of type BusinessData");
        }
    }

OTHER TIPS

Thanks to Brian Abrams on the MSDN forums I have figured this out. When you create a BCS based, external data column within a SharePoint list there is another, hiddne field created for you. This is given the name yourFieldName_ID so that if your field is called "Industry" the hidden field is called Industry_ID. This holds the BCS entity id for the entity in question. Basically all I did was update this column with the value from the original list and the items display properly in the SharePoint GUI.

IMO, in addition to being poorly documented this is just simply horrible. The purpose of having an API is to abstract away these sorts of complexities. It also means that the ACID principles are just simply contrived within an EDC. I can quite clearly set the ID and the text value to completely different things.

String new_value = properties.AfterProperties[MarketNeedFieldNames.Industry_Internal].ToString();
SPBusinessDataField ind = (SPBusinessDataField)item.Fields[MarketNeedFieldNames.Industry_Internal];
ind.ParseAndSetValue(item, new_value);
item[MarketNeedFieldNames.Industry_Internal + "_ID"] = properties.AfterProperties[MarketNeedFieldNames.Industry_Internal + "_ID"].ToString();

try this code for setting external field in sharepoint list :

// "Project ID" is the BDC column in list
SPBusinessDataField dataField1 = oSPFile.Item.Fields["Project ID"] as SPBusinessDataField; 

dataField1.ParseAndSetValue(oSPFile.Item, ProjectID.ToString());  //Set your value here

oSPFile.Item[dataField1.RelatedField] = oSPFile.Item.Fields["Project ID"];
Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top