Business Connectivity Services (BCS) with Oracle using Visual Studio 2010 – Part 1

In my last post I’ve explained steps to connect SQL Server using BCS and SharePoint Designer 2010. However, SPD 2010 doesn’t provide such option to connect Oracle. Here we require Visual Studio 2010 to create BDC model which connects Oracle. Here are the steps,

  • Create new project selecting Business Data Connectivity Model template .

  • Provide location of your SharePoint server

  • Rename the entity model with appropriate name ,

  • Open Solution Explorer and rename ( optional ) Entity.cs to Training.cs and add your properties ,

  • In ReadItem section, Modify identifier1 to DOCID and update returnParameter section with actual properties added in above step. Make sure to update Name and TypeName properties as per Training.cs.

  • In ReadList section, Remove existing Entity1 section and copy ReadItemEntity section from ReadItem section.

  • Make sure to change the Identifier1 to DOCID, here is my complete BDC model

  • Open Solution Explorer and add Oracle.DataAccess dll in References.

  • Open TrainingEntityService.cs file and add your code for ReadItem and ReadList functions . Here is my code for the same,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Oracle.DataAccess.Client;

namespace BdcTrainingModel.BdcModel1
{
    /// <summary>
    /// All the methods for retrieving, 
    ///updating and deleting data are implemented in this class file.
    /// The samples below show the finder and specific finder method for Entity1.
    /// </summary>
    public class TrainingEntityService
    {
        /// <summary>
        /// This is a sample specific finder method for Entity1.
        /// If you want to delete or rename the method think 
        ///about changing the xml in the BDC model file as well.
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Entity1</returns>
        public static Training ReadItem(string id)
        {
            Training evt = null;
            string connectionstr= "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)
                                  (HOST=server_name)(PORT=1569))
                                  (CONNECT_DATA=(SERVICE_NAME=service_name)));
                                  user id=user;password=password;";
            OracleConnection con = new OracleConnection(connectionstr);

            string sqlQuery = "SELECT * FROM T_TRAINING WHERE DOCID='"+id+"'";

            try
            {
                evt = new Training();
                OracleCommand thisCommand = new OracleCommand(sqlQuery, con);
                con.Open();
                thisCommand.ExecuteNonQuery();

                using (OracleDataReader thisReader = thisCommand.ExecuteReader())
                {
                    if (thisReader.Read())
                    {
                        evt.DOCID = thisReader.GetValue
                                  (thisReader.GetOrdinal("DOCID")).ToString();
                        evt.DOCAUTHOR = thisReader.GetValue
                                  (thisReader.GetOrdinal("DOCAUTHOR")).ToString();
                        evt.RKPI_CONDUCTEDLEDBY = thisReader.GetValue
                                  (thisReader.GetOrdinal("RKPI_CONDUCTEDLEDBY")).ToString();
                        evt.RKPI_TYPE = thisReader.GetValue
                                  (thisReader.GetOrdinal("RKPI_TYPE")).ToString();
                        evt.RKPI_SUMMARY = thisReader.GetValue
                                  (thisReader.GetOrdinal("RKPI_SUMMARY")).ToString();
                        evt.RKPI_DATE = DateTime.Parse(thisReader.GetValue
                                  (thisReader.GetOrdinal("RKPI_DATE")).ToString());
                    }

                }

                return (evt);
            }
            catch (Exception ex)
            {
                evt.DOCID = id;
                evt.DOCAUTHOR = ex.Message;
                evt.RKPI_TYPE = ex.Message;
                evt.RKPI_SUMMARY = ex.Message;
                evt.RKPI_DATE = DateTime.MinValue;
                evt.RKPI_CONDUCTEDLEDBY = sqlQuery;
                return (evt);
            }
            finally
            {
                con.Dispose();
            }
        }
        /// <summary>
        /// This is a sample finder method for Entity1.
        /// If you want to delete or rename the method think
      /// about changing the xml in the BDC model file as well.
        /// </summary>
        /// <returns>IEnumerable of Entities</returns>
        public static IEnumerable<Training> ReadList()
        {
            string connectionstr= "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)
                                  (HOST=server_name)(PORT=1569))
                                  (CONNECT_DATA=(SERVICE_NAME=service_name)));
                                  user id=user;password=password;";

            OracleConnection con = new OracleConnection(connectionstr);

            string sqlQuery = "SELECT * FROM T_TRAINING";

            List<Training> allEvents;
            try
            {
                allEvents = new List<Training>();
                OracleCommand thisCommand = new OracleCommand(sqlQuery, con);
                con.Open();
                thisCommand.ExecuteNonQuery();

                using (OracleDataReader thisReader = thisCommand.ExecuteReader())
                {
                    // Always call Read before accessing data.
                    while (thisReader.Read())
                    {
                        Training evt = new Training();

                        evt.DOCID = thisReader.GetValue
                                   (thisReader.GetOrdinal("DOCID")).ToString();
                        evt.DOCAUTHOR = thisReader.GetValue
                                   (thisReader.GetOrdinal("DOCAUTHOR")).ToString();
                        evt.RKPI_CONDUCTEDLEDBY = thisReader.GetValue
                                   (thisReader.GetOrdinal("RKPI_CONDUCTEDLEDBY")).ToString();
                        evt.RKPI_TYPE = thisReader.GetValue
                                   (thisReader.GetOrdinal("RKPI_TYPE")).ToString();
                        evt.RKPI_SUMMARY = thisReader.GetValue
                                   (thisReader.GetOrdinal("RKPI_SUMMARY")).ToString();
                        evt.RKPI_DATE = DateTime.Parse(thisReader.GetValue
                                    (thisReader.GetOrdinal("RKPI_DATE")).ToString());
                        allEvents.Add(evt);
                    }
                }

                //thisReader.Close();

                Training[] eventList = new Training[allEvents.Count];
                for (int evtCounter = 0;
                  evtCounter <= allEvents.Count - 1;
                  evtCounter++)
                {
                    eventList[evtCounter] = allEvents[evtCounter];
                }
                return (eventList);
            }
            catch (Exception ex)
            {
                Training[] errEventList = new Training[1];

                Training errEvt = new Training();
                errEvt.DOCID = ex.Message;
                errEvt.DOCAUTHOR = ex.Message;
                errEvt.RKPI_TYPE = ex.Message;
                errEvt.RKPI_SUMMARY = ex.Message;
                errEvt.RKPI_CONDUCTEDLEDBY = ex.Message;
                errEvt.RKPI_DATE = DateTime.MinValue;
                errEventList[0] = errEvt;

                return (errEventList);
            }
            finally
            {
                con.Dispose();
            }
        }
    }
}
  • Build and deploy the project . If you get following error while deployment ,

Error occurred in deployment step ‘Add Solution’: The default web application could not be determined. Set the SiteUrl property in feature BdcTrainingModel_Feature1 to the URL of the desired site and retry activation.

Add following line in Feature1.Template.xml file

 <Property Key=’SiteUrl’ Value=’your_site_url’/>

  • Once successfully deployed, Go to SharePoint central administration and set required permissions for your newly deployed Business Data Connectivity Service Application

  • Finally create new External list and verify the solution . Here is the result,

You may notice Edit item button is disabled, It’s because I haven’t added any Update method. I will add create,update and delete methods in next part of this series.

Drop me an e-mail if anyone is interested in project source files.

Advertisements

Connecting Oracle using ODP.NET on Windows x64

Recently I’ve worked very hard to find correct package and working solution to connect Oracle database using ODP.NET on Windows x64. I wish others won’t get the same pain as I had so documenting what I’ve done for the same.

If you are doing fresh installation then you may skip this cleaning steps otherwise you should consider cleaning up Oracle completely from your workstation. To do so,

  • Use Oracle uninstaller to remove Oracle from your machine.
  • In case you don’t have uninstaller remove Oracle directory manually from your machine including registry keys, Path environment variable , Oracle services from registry . You can get plenty of post on Internet for the same. Once done restart your machine.
  • Next to find out number of Oracle ODP.net dlls,policy file still registered in GAC , To do so try following script  ,

gacutil /l | find /i “Oracle” > c:\Oracle_versions\oracle.txt

             Once executed you will get list of dlls,policy files registered in your machine.

  • It’s time to remove all old GAC entries , To do so try something like ( Replace with actual dll and policy file name )

gacutil /u Oracle.DataAccess
gacutil /u Policy.9.2.Oracle.DataAccess
gacutil /u Policy.10.1.Oracle.DataAccess
gacutil /u Policy.10.2.Oracle.DataAccess

OR,

gacutil /u “Oracle.Management.Omo, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86”
gacutil /u “Oracle.VsDevTools, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86”
gacutil /u “Oracle.Web, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86”
gacutil /u “Policy.2.102.Oracle.DataAccess, Version=2.111.7.20, Culture=neutral, PublicKeyToken=89b483f429c47342, processorArchitecture=x86”
  • Once done , restart your machine.

Now it’s time to install Oracle client and ODP.NET . Here are recent compatible version with Windows x64

To get Oracle ODP.NET and .NET Application running on Windows x64 machine for x86 application

  • Install Oracle client “Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x64) “ from here ,

http://www.oracle.com/technetwork/database/enterprise-edition/downloads/112010-win64soft-094461.html

Select “Run Time” option while installing

  •  Install ODAC 32 bit driver “ODAC 11.2 Release 3 and Oracle Developer Tools for Visual Studio (11.2.0.2.1)” from here ,

http://www.oracle.com/technetwork/topics/dotnet/utilsoft-086879.html 

( While installing Windows will complaint “ You are installing unsupported version of software” , don’t listen it and just go with installation ) Compile .NET application with “Any CPU” or “x86” processor type and application should able to connect Oracle. ( I assume before installing above prior versions of Oracle dlls from GAC, policy files , registry cleanup , and machine.config is done ) To get Oracle ODP.NET and .NET Application running on Windows x64 machine for x64 application ( In case of SharePoint deployment )

  •  Install Oracle client “Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x64) “ from here ,

http://www.oracle.com/technetwork/database/enterprise-edition/downloads/112010-win64soft-094461.html 

Select “Run Time” option while installing

  • Install ODAC 64 bit driver “64-bit ODAC 11.2 Release 3 (11.2.0.2.1) for Windows x64 “ from here ,

http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html

( Select the same Oracle home as of above client.It’s command based installation so make sure you use file path correctly ).On my machine this installation is like , Client_1 is for Oracle client and Client_2 for ODAC)