Thursday, October 22, 2009

Convert VB.NET to C#

Convert From VB.NET to C#

ODP.NET Developer's Guide

A good book. Examples in Visual Basic. Can be converted to c# quite easily.

ODP.NET Developer's Guide
Oracle Database 10g Development with Visual Studio 2005 and Oracle Data Provide for .Net

A practical guide for developers working with Oracle Data Provider for .Net and the Oracle Tools for Visual Studio 2005

Jagadish Chatarji Pulakhandam
Sunitha Paruchuri

PACKT Publishing
Birmingham-Mumbai

Tuesday, October 13, 2009

Using the new ODP.Net to access Oracle from C# with simple deployment

http://splinter.com.au/blog/?p=156
Still tracking comments as of 13-Oct-2009

Microsoft has deprecated System.Data.OracleClient, so here's a simple example of using the new ODP.NET Oracle.DataAccess.Client, with the following benefits:
* Simple Xcopy deployment
* No Oracle [instant] client installation needed
* No TnsNames.Ora file needed

Firstly, download the ~200mb ODP.Net from Oracle. Don't freak out, you won't need to redistribute *all* this with your app, just ~30megs worth. I used this version:http://www.oracle.com/technology/software/tech/windows/odpnet/index1110710beta.htmlYou'll probably want to get the latest version from here:http://www.oracle.com/technology/tech/windows/odpnet/index.html

Grab Oracle.DataAccess.dll from ODAC1110710beta.zip\stage\Components\oracle.ntoledb.odp_net_2\11.1.0.7.10\1\DataFiles\filegroup4.jar. Copy it into the same folder as your project's Program.cs. In Visual Studio, right click references and add the Oracle.DataAccess.dll.

Write some code like this in your app:

using Oracle.DataAccess.Client; // This goes up the top
...
string connstring =
"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=myhost)(PORT=1527))" +
"(CONNECT_DATA=(SID=mysid)));User Id=myuserid;Password=mypassword;";
using (OracleConnection conn = new OracleConnection(connstring))
{
conn.Open();
string sql = "select distinct owner from sys.all_objects order by owner";
using (OracleCommand comm = new OracleCommand(sql, conn))
{
using (OracleDataReader rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetString(0));
}
}
}
}


You'll then need the following dll's to be placed in the same folder as your EXE:
* oci.dll (called 'oci.dll.dbl' in ODAC1110710beta.zip\stage\Components\ oracle.rdbms.rsf.ic\11.1.0.7.0\1\DataFiles\filegroup2.jar)
* Oracle.DataAccess.dll (in ODAC1110710beta.zip\stage\Components\ oracle.ntoledb.odp_net_2\11.1.0.7.10\1\DataFiles\filegroup4.jar)
* oraociicus11.dll (in ODAC1110710beta.zip\stage\Components\ oracle.rdbms.ic\11.1.0.7.0\1\DataFiles\filegroup3.jar)
* OraOps11w.dll (in ODAC1110710beta.zip\stage\Components\ oracle.ntoledb.odp_net_2\11.1.0.7.10\1\DataFiles\filegroup3.jar)

You may need the following dll's, but I didn't. I'd get them anyway, just to be safe, as some people say they're needed:
* orannzsbb11.dll (in ODAC1110710beta.zip\stage\Components\oracle.ldap.rsf.ic\11.1.0.7.0\1\DataFiles\filegroup1.jar)
* oraocci11.dll (in ODAC1110710beta.zip\stage\Components\ oracle.rdbms.rsf.ic\11.1.0.7.0\1\DataFiles\filegroup3.jar)
* ociw32.dll (called 'ociw32.dll.dbl' in ODAC1110710beta.zip\stage\Components\ oracle.rdbms.rsf.ic\11.1.0.7.0\1\DataFiles\filegroup2.jar)

If you get the exception 'The provider is not compatible with the version of Oracle client', don't stress, simply retrace your steps and make sure you get ALL those DLL's from the same ODP.Net / ODAC distribution to avoid version number conflicts, and put them all in the same folder as your EXE.

If you download a newer version of ODP.Net, the jar files that enclose the dll's may have moved, so you'll have to manually search through them all, don't worry it won't take *too* long!

Good luck!

Comments:

21-Aug-2009
Don't forget to rename the ".dll.dbl" files to ".dll"; otherwise you'll get the exception.Thank you Chris. This was very helpful.

11-Sep-2009
Thankyou Chris, this solution is great and works really well. In fact, my multithreaded app (which does a LOT of queries) performs 57% faster when using your redist pack

7-Oct-2009

Hi Chris, thanks for the tip. this is really great.

I do however have a question, we only include the dll and not referencing it through the project, i.e. but instantiate it using the System.Data.provider factories, then we do need to use gacutil to install it in the global assemblycache. Is that correct?

SO as an example if I refer this dll in my config as:
Now if I call using the .NET standard classes (System.Data), I can instantiate the oracle connection/command etc by getting its provider factory through below call:

DbProviderFactories.GetFactory(ConfigurationManager.ConnectionStrings[_dbName].ProviderName);

where _dbName just some variable of the database name.

However, this means that the DLL stills needs to be installed in the GAC using gacutil.exe.
THanks in advance for reading ths.

7-Oct-2009
Hi 'Kts',I believe you're on the right track there. That does give you the flexibility to use the same code for any database (sql, oracle, postgres, etc). But i think you'd then have to work with the System.Data.Common.* types (eg System.Data.Common.DbConnection). These types are a bit more generic and may have less of the oracle-specific data types, however if you can get it to work then its a great idea!Also, i'm personally not a fan of the GAC but if it works for you then go for it.

13-Oct-2009

Hi ChrisThanks for the informative write up. I downloaded the XCOPY version of Oracle 11g ODAC 11.1.0.7.20 and with that the only large file is the oraociei11.dll which is 114MB and looks like that is reqd in the EXE folder. Did you notice the same thing ?
thanksSunit

13-Oct-2009
Hi Sunit,I wasn't aware of an XCOPY version. Give it a try with only that file, maybe it'll work? Let us know if it works.114megs is pretty big though, the files i described above are only ~30megs.Still, maybe it supports features that my bare-bones method doesn't. Could be worth remembering!Cheers

Using Microsoft .NET and C# with Oracle 9i

http://www.aspfree.com/c/a/.NET/Using-Microsoft-dot-NET-and-C-sharp-with-Oracle-9i/

Oracle provides a software tool called ODP.NET that allows connectivity between the .NET languages and an Oracle database. This interface is a set of tools that allow the creation of .NET objects that connect directly to Oracle databases. Learn the basics of connecting to and performing simple queries to an Oracle database.

Prerequisites

Let’s face it -- neither Microsoft nor Oracle really wants to see their two flagship products work together. Microsoft would rather see a programmer use C# with SQL Server, Access, or just a plain XML data file before connecting to an Oracle data source. Oracle, on the other hand, has committed firmly to the J2EE development system for major development involving their databases.

However, Oracle does provide a software tool called ODP.NET that allows connectivity between the .NET languages and an Oracle database. This interface is a set of tools that allows the creation of .NET objects that connect directly to Oracle databases. This, at the very least, allows applications to connect to and make use of the power and capability of an Oracle database. It includes support for regular SQL queries and updates, stored procedures, and reading data from an Oracle record set into a .NET DataSet object, among other things. This article will cover the basics of connecting to and performing simple queries to an Oracle database using this set of objects.

First we’ll look at the set-up required to perform these tasks. If you are going to work with ODP.NET in ASP.NET applications, you will, obviously, need a web server with IIS and the .NET Framework installed and running. I will not be covering the steps needed to set up an IIS Web Application, as I will be focusing on actually working with the database.

If you are only working on a stand-alone application, you will just need the .NET Framework installed. In both cases, you will probably want some sort of development environment to allow easy editing of .NET code. Next, you will need to install the ODP.NET data provider on the web server if you are using ASP.NET or on your local machine if you are writing a stand-alone app. Also, each computer that will access the database as a client will need the Oracle client software installed. ODP.NET is a client-side library, and will need to be installed with your application if you are thinking of distributing your application widely. One of the nice things about ODP.NET is that it doesn’t require any extra configuration of the Oracle server. You can download the ODP.NET driver from the Oracle website at:

http://otn.oracle.com/software/tech/windows/odpnet/index.html

The first important thing to recognize about ODP.NET for Oracle 9i is that it contains two namespaces, first Oracle.DataAccess.Client. This contains the actual working classes for connecting to and acting on the Oracle database. The second namespace is Oracle.DataAccess.Types. This namespace has all the classes and methods required when working with specific Oracle data types. In this article, we won’t deal with the Types namespace at all. There are several classes to take note of in Oracle.DataAccess.Client and these are:

OracleConnection -- The basic class for connecting to a database

OracleCommand -- A class that represents a database command, either a text query or a stored procedure

OracleDataAdapter -- This class allows the programmer to pipe a returned Oracle record-set into a .NET DataSet

OracleParameter -- This class represents all the attributes and information in a stored procedure parameter

OracleDataReader -- This class represents a simple, read only data set, useful for quickly getting small, simple results, or data you will not want to change

Each of these classes will become very important in the future when we look a connecting to and working with an Oracle database.

Connecting to a Database

The process for connecting to an Oracle database is very straightforward, especially for anyone who has worked with the .NET database connection classes for SQL Server. Oracle basically copied the same class structure that Microsoft used in the SQL Server connection classes already present in .NET. This makes moving over from SQL Server to Oracle relatively easy. It also means that a lot of examples describing database interaction with SQL Server can easily be modified to work with Oracle. In any case, here is a quick overview of the steps required to connect to an Oracle database.

When working with a database, we must create an OracleConnection object to retain all information for communicating with the database. First, we import the required assemblies.
using Oracle.DataAccess.Client; using System.Data; Next, we create the connection string with the user credentials information. In this case, the Oracle schema is user1 the password is mypass and the Oracle database name either in the tnsnames file or in the Oracle Internet Directory is db.

String connString = “User id=user1;Password=mypass;source=db”;

Now, the connection object, conn, is created using the connection string.

OracleConnection conn = new OracleConnection(connString);

The last step is to begin communication with the database using the Open() method.

conn.Open();

This creates a connection to a database and opens it. The most important part is making sure the connection string is correct. Each different type of database uses a different connection string and the differences in syntax can be a problem if you don’t pay close attention to them.

Creating a Command

In this section, we look at creating the main workhorse class and its attributes and capabilities. The OracleCommand class has two main functions. First, you can give it a simple SQL query string and execute that command on the database. Secondly, you can use the OracleCommand object to execute a stored procedure on the database.

The query string is the simplest use of this command and we will look at it first.

First, create the command by using the factory method CreateCommand() method on the OracleConnection object.

OracleCommand cmd = conn.CreateCommand();

This creates a command object attached to the conn connection. Alternatively, the command object can be created using its own constructor and then set the Connection field later:

OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;

After creating the command, we must set the CommandText attribute to give the object the actual string containing the SQL query it will run on the database. The code below also sets the CommandType attribute, which selects whether CommandText is a text command or the name of a stored procedure (this defaults to Text):

String query = “select * from users”;
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;

The last step to complete is to run the command on the database and catch the results in an OracleDataReader object.

OracleDataReader reader = cmd.ExecuteReader();

This executes the command on the database and puts the results in reader. There is an important distinction between queries that read data and those that only update data. When your command reads data, you use the ExecuteReader() method to get this data back. However, when all your command does is insert or update data with nothing meaningful to return, you would use the ExecuteNonQuery() method which we will cover later.

The other mode that OracleCommand can operate in is for executing a stored procedure. This process works somewhat differently than when executing a straight text command.
Everything is the same as above until we set the command text string. In this case, the CommandText attribute is set to the name of the stored procedure. In the following case, this is a stored procedure to get back users in a certain range of user_id’s, called GetUsers. Notice also how the following code sets the CommandType attribute to StoredProcedure:

cmd.CommandText = “GetUsers”;
cmd.CommandType = CommandType.StoredProcedure;

After setting the stored procedure name and command type, we must add parameters to the OracleCommand object. This involves creating multiple OracleParameter objects and adding them to the OracleCommand’s Parameter member. This is done in the following manner:

cmd.Parameters.add(new OracleParameter(“start_user”,OracleDbType.Int, 202));

This code creates a parameter to the stored procedure GetUsers called start_user which is of type Int and has the value 202. This object is then added to the OracleCommand’s Parameters collection that stores all of the different parameters to the stored procedure. There are several things to note here. First of all, when creating multiple parameters, the number of parameters must match the number of parameters expected by the stored procedure. It is also a good idea to match up order so that parameter objects are added to the Parameters collection in the same order that they appear in the stored procedure definition to make debugging easier.

After adding the second parameter, ExecuteReader is called to get the results from the database.

cmd.Parameters.add(new OracleParameter(“end_user”, OracleDbType.Int, 210));
OracleDataReader reader = cmd.ExecuteReader();

This has shown the basics of reading data out of the database. The next step is to take that data and turn it into a .NET DataSet that can be bound to a data driven control or iterated over and changed to later update the database.

Creating a DataSet from and Oracle Database

The first step to creating a DataSet from an Oracle database is to make use of a new secondary class, called the OracleDataAdapter. This class basically takes the data as it comes back from Oracle and parses it into a .NET DataSet. Another useful characteristic of this class is that it takes the place of an OracleCommand object. The OracleDataAdapter contains the command string and parameter objects required to execute a command (either text or stored procedure) on the database. There are several ways to create an OracleDataAdapter object. However, the one shown below uses an OracleConnection object and a string to become the Select command.

OracleDataAdapter adapter = new OracleDataAdapter(conn, “select * from users”);
DataSet set = new DataSet();
adapter.fill(set, “users”);

After creating the OracleDataAdapter we create a DataSet object to take the results of the select statement. Then, we use the fill method to populate a DataTable object named “users” inside the DataSet with the data returned from the select statement. Now, you can do all the fun, nifty things you could always do with a DataSet, such as binding it to data driven controls, modifying the data and putting it back into the database. The OracleDataAdapter also contains data members to hold insert, update, and delete commands, so the object can even automate maintaining data in the database in the same state as the DataSet in memory. However, those functions are beyond the purview of this article.

Final Words

Overall, the ODP.NET class framework follows many of the normal conventions that any database programmer finds in other such frameworks. This makes is relatively easy to learn and pick up on for the experienced database programmer, and even for the novice, the classes are laid out in a logical way that makes understanding each ones function easy.