Read the BDC data from MOSS Object Model

So, what do you do the first when you want to create a rock-solid BDC system with your SharePoint?

If your BDC is going to fetch it’s data from the web service, you will of course first create the service, which must contain at least two methods: the IdEnumerator and SpecificFinder compliant methods (to simplify: IdEnumerator compliant method returns just a set of the "primary keys" for all the data your BDC system is offering, and SpecificFinder compliant method returns all the data for a given, specified "primary key".

Then, you have read Rolf’s post about proper way of configuring the BDC to work with your web services.

You have imported your BDC into Applications, created a web part to display the BDC data in the SharePoint site, and everything is going well.

Now, you need to use this BDC data in the SharePoint Object model. It’s trickier then one might think, but still quite straight-forward once you get it.

In this code example, I’ll show how to connect to the SharedServices, select the Application instance from the SharedServices, and Entity from the ApplicationInstance. Then I’ll invoke the IdEnumerator to get the list of all the keys, and then invoke specific finder over every single key.

As I have said, quite straight-forward once you figure it out Smile

//
//let's first say which SharedServices are we going to use
//
SqlSessionProvider.Instance().SetSharedResourceProviderToUse("SharedServices1");

//
//for fun, let's just list all application insances registered in SharedServices
NamedLobSystemInstanceDictionary sysInstances = ApplicationRegistry.GetLobSystemInstances();
m_LogText.AppendText("Installed BDC Applications: " + Environment.NewLine);
foreach (string applicationName in sysInstances.Keys)
    m_LogText.AppendText(applicationName + Environment.NewLine);


//
//let's take our instance we acutually want to use
LobSystemInstance erpLobAppInstance = sysInstances["ERPServices_Instance"];

//
//Let's list all entities which are in this instance
NamedEntityDictionary entities = erpLobAppInstance.GetEntities();
foreach (string key in entities.Keys)
{
    Entity entity = entities[key];
    m_LogText.AppendText("Entity: Key - " + key + " - ID - " + entity.Id.ToString() + Environment.NewLine);
}

//
//let's take entity we actually need
Entity lobEntity = entities["Partner"];


//
//entity contains all the info we need for the further work - 
//methods, results...
//let's read info about the fields cointained in the SpecificFinder result
//means, when we execute SpecificFinder (method that returns one specific record based on
//the id (primary key) of that record
Field fieldID = lobEntity.GetSpecificFinderView().Fields.Find(delegate(Field f) { return (f.Name == "PartnerId"); });
Field fieldPartnerName = lobEntity.GetSpecificFinderView().Fields.Find(delegate(Field f) { return (f.Name == "PartnerName"); });
Field fieldPartnerAddress = lobEntity.GetSpecificFinderView().Fields.Find(delegate(Field f) { return (f.Name == "Address"); });

//
//let's now read all the methods which are contained in the entity
IEnumerator<string> methodsInEntity = lobEntity.GetMethodInstances().Keys.GetEnumerator();

//this is a very important step, because, we can, for example, directly invoke
//SpecificFinder method (Entity.FindSpecific()), 
//but we can not do the same for IdEnuumerator method
//we have now to iterate through all entity methods to find our IdEnumerator
MethodInstance idEnumeratorMethod = null;
while (methodsInEntity.MoveNext())
{
    //let's read the name and the type of the current method
    String methodName = (String)methodsInEntity.Current;
    MethodInstance thisMethod = (MethodInstance)lobEntity.GetMethodInstances()[methodName];

    //if the current method's type is "IdEnumerator", that's exactly what we need
    String methodType = thisMethod.MethodInstanceType.ToString();
    if (methodType.Equals("IdEnumerator"))
    {
        idEnumeratorMethod = thisMethod;
        break;
    }

}

//
//let's now execute the idEnumeratorMethod, and get all the instances (result)
//which it returns, 
//IdEnumerator results usually contains only "ID", but can also contain 
//the creatation date or some other system field
IEntityInstanceEnumerator idEnumeratorInstances = (IEntityInstanceEnumerator)lobEntity.Execute(idEnumeratorMethod, erpLobAppInstance);

//
//let's now iterate through the results the IdEnumerator method has returned
//and let's get our IDs from the IdEnumerator result
while (idEnumeratorInstances.MoveNext())
{
    //take the result
    IEntityInstance idEnumeratorResultIntstance =
        (IEntityInstance)idEnumeratorInstances.Current;

    //convert this result (IEntityInstance) to the DataRow for easier manipulation
    DataRow row = idEnumeratorResultIntstance.EntityAsDataRow(idEnumeratorResultIntstance.EntityAsDataTable);

    //let's now take the primary key we actually wanted from the beginning
    Object primaryKeyValue = row["PartnerId"];

    //now, let's call the SpecificFinder method over this primary key (ID)
    //on that way we will get all the data we have for that object
    IEntityInstance specificFinderResult = lobEntity.FindSpecific(primaryKeyValue, erpLobAppInstance);

    //let's pick up the result values
    string pid = specificFinderResult[fieldID].ToString();
    string pname = specificFinderResult[fieldPartnerName].ToString();
    string paddress = specificFinderResult[fieldPartnerAddress].ToString();

    //and display them on the screen...
    m_LogText.AppendText(pid + " - " + pname + " - " + paddress + Environment.NewLine);

}