StrataFrame Forum

Accessing ORACLE with SQL SERVER generated Business Object (Problem)

http://forum.strataframe.net/Topic18954.aspx

By Ertan Deniz - 9/3/2008

Business Object was filled from ORACLE. (Table)

But When I 'm trying to access "id" property getting the error "specified cast is not valid".

Id property (Int32), Datatable.Column.type is System.Decimal. (ORacle table column is NUMBER").

I've run the query through FillDataTable("Select statement") command.

public System.Int32 id

{

get

{

return (System.Int32)this.CurrentRow["id"];

}

set

{

this.CurrentRow["id"] = value;

}

}

By Dustin Taylor - 9/4/2008

All numbers in Oracle are stored as floating point numbers, so they come out as decimal. To ensure that you can return it as an integer, use the System.Convert.ToInt32() method instead of casting it as an integer.
By Ertan Deniz - 9/4/2008

But Business Object is generated based on SQL SERVER table.

The cast operation was generated by StrataFrame. If I change the cast operation to System.Convert.ToInt32(), next generation will overwrite.

What can I do in this case ?

By Greg McGuffey - 9/5/2008

I'd suggest using the custom code area in the BO mapper. Then it won't get overwritten.
By StrataFrame Team - 9/5/2008

OK, so the business object was built against a SQL Server table through the business object mapper, but you're using ORACLE to populate the business object at runtime? 

If so, then there's you're problem.  When you build the business object against a database at design-time, then it's highly recommended that you execute the business object against the same database type at runtime.  So, if you use the BOMapper to build the schema against the ORACLE table, then all of those Int columns will be changed to System.Decimal instead.  Then, your code that accesses the business object can worry about the type conversions.

By Ertan Deniz - 9/5/2008

My need is very clear. I want to support both ORACLE and SQL SERVER at the runtime over single business object in my project. I've read linked post. Trent has said that

"The BOs do not know or care about where the data comes from.  The only time that you will have an issue in regards to the BO is if you are creating custom queries (SqlCommand / OracleCommand) and then executing that command via a FillTableThe BOs do not know or care about where the data comes from.  The only time that you will have an issue in regards to the BO is if you are creating custom queries (SqlCommand / OracleCommand) and then executing that command via a FillTable"

 http://forum.strataframe.net/Topic16974-6-1.aspx

So, I've worked on a few days to be successful on my requirement. Generating business objects from two data sources and manage the true instance complicates my work. It is not acceptable.

If there will be a solution, it have to be developed easily.

What should I do ? Does strataframe solves my requirement ? Please respond quickly.

By Ertan Deniz - 9/5/2008

I' ve also found one critical point.

CreateDbParameter function of OracleDataSourceItem tries to set nativeDbType. But  it assumes object is generated based on ORACLE Table. (See code below.)

'-- First set the native db type

loReturn.OracleType = CType(QueryInfo.FieldNativeDbTypes(FieldName), OracleType)

So, We can not support SQL and ORACLE with the single object.

I wonder If Microfour or any other customer implement this case.

Can we progress with the customization of the framework or MicroFour can do this for the users of strataframe ?

Not : Plus, StrataFrame have to handle the case sensitivity needs on field names and tablenames.

By Ertan Deniz - 9/8/2008

Any comment ? No comment, When I need quick responce !
By Dustin Taylor - 9/9/2008

If you are wanting to do this without re-creating the objects in the BO Mapper using Oracle as the DB source, I would create a shared method someplace that will do a type conversion for you. A good place for this would be your base business object, use the FieldAccessing event (you can enable the event in the BO Mapper), to call your shared method whenever the field is accessed and parse the necessary conversions and such for you.

The bottom line is that this is a fairly custom scenario (creating the BO Mapper metadata using one database type and deploying to a seperate data base type) that you will need to account for. It will take some work up front, but it can certainly be done.

By Ertan Deniz - 9/9/2008

I don't think this is a custom scenario. I expect you to solve all these requirements in the framework.

There are many points in my post to say something about.

What about Createparameter method ? What is your solution ?

Any StrataFrame customer implemeting the case ? Microfour ?

Please let us work on this issue together. This is not easy as putting a shared method somewhere.

By David Daragon - 9/11/2008

Hi,

I want to do the same as Ertan. So, I'm interessed by this topic.
If I understand, :

For the moment, if I want to execute my application with SQL database I must to build the schema against the SQL table and if I want to execute my application with Oracle database I must to build the schema against the Oracle table.

So, I need to have 2 BO for the same table with parameters of each database.

I hope there will be a solution soon.

Regards,
David

By Trent L. Taylor - 9/12/2008

Well, let's get to the crux of this topic as this is not going to be a quick post and falls more on the side of consultation.  This can become a very deep and complex topic which is not the intent of the forum.  But here is the bottom line when you are trying to do something like this (which is possible but requires some good foundation laying).

You should always create a base BO which all of your BOs within your application inherit from.  So let's just say BaseBO.  Within this base BO, I am going to overwrite the FillDataTable method.  I may need to override several others as well before all is said and done in order to take the automatic conversion into account.

When writing your application, you will always want to create your queries, etc. towards a specific database (i.e. SQL Server).  Now let's assume that you have the need to implement Oracle.  I will create a shared property within my application to which the BaseBO looks.  If it is set to Oracle, then anytime that the FillDataTable is called, the BaseBO will automatically convert an SqlDbCommand into an OracleDbCommand.  This is the approach that we have used within our medical software and it has worked just fine.

Next, you may need to "scrub" all values through an Accessing event or by overriding or shadowing the CurrentRow property or something along those lines if there are type conversion issues.  But again, this will be done within the BaseBO so that you only have to place this logic in a single location.

By Ertan Deniz - 9/15/2008

I'm waiting for Strataframe developers to give me guidance and roadmap.
By Trent L. Taylor - 9/17/2008

Ertan,

I thought that we had.  I am unsure of what you are wanting from us.  We have given you all of the advice that we had intended to give on this particular topic.  Creating the solution for you is far more in depth and complex.  Now if you get stuck within a very specific section and want to discuss that section or detailed item then we can, but past that I feel as though we have done all that has been required by trying to give you that "roadmap" without actually coding the logic for you.

By Ertan Deniz - 9/22/2008

Sorry, I've not seen your response because I've forgotten to look at the next page. So, I've written a post about waiting guidance and roadmap.

I've understood your advice for external queries. But What about queries generated by strataframe. ? I've found a point that I've written above as a post. As explained in that post, INSERT,UPDATE and Delete queries can not be executed because there is a need for type conversion from SQL TO ORACLE. This is the critical point. The case have to be solved by Strataframe developers.

I've solved  for the external queries. 

By Trent L. Taylor - 9/23/2008

Actually this is not something that needs to be changed by SF developers, but rather something that you should take into account in your application.  We have no intention of making the SqlDataSourceItem try and figure out of a data type should be converted into an Oracle item..this would break a lot of peoples applications and is not something that we are going to do.

Now, since you have this need, you can do this quite easily yourself.  You already have your application setup to determine if you are running SQL or Oracle and since you have this need, this would be my suggestion.  Create your own data sources.  You have the SF source code, so you can copy the code from the SqlDataSOurceItem and create your own...or just inherit from the SqlDataSOurceItem and override the CreateDbCommand (probably the better route) and then take this into account yourself.  You can copy the code from the SqlDataSourceItem or the OracleDataSourceItem so that you can see exactly what the CreateDbCommand is doing and then adjust this to meet your needs.  This is going to be the route that you will need to take...and it doesn't require anything whatsoever to be done within the framework itslef but rather is specific to your application.