Google

Friday, February 02, 2007

No Oracle DLinq Support

Recently I had a chance to play around with DLINQ that came out in the "Microsoft Visual Studio Code Name “Orcas” - LINQ CTP (May 2006)". I was blown away by the ability to create a Data Access Layer with out writing a single sql statement.

DLINQ stands for Database Language INline Query. What this means is that we no longer have to write sql statements as strings but can compile them as constructs of the application and let the provider module build the proper query for us at execution time based on the IL that was generated. Seeing this in action was unbelievable.

I spent a good bit of time reading all the material and examples and just couldn't wait until I could try it out with Oracle. It didn't take me long to determine that there was no Oracle support built in to the product. The reading that I did did point out that there is a framework in place for any provider to create their own LINQ module. As of yet, I have found no information stating that Oracle is or plans on making an Oracle DLINQ provider.

For those of us Oracle Developers out there this is a must have in the future. Hopefully Oralce will not make us wait too long for it.

Tuesday, October 24, 2006

.Net 2.0 and JavaScript

Up until now, most sites built by ASP.NET developers have had post-backs to manipulate the user interface to provide some feedback to the user. This was probably due to the lack of JavaScript knowledge. Due to recent activity on the use of AJAX, its hard not to need JavaScript in almost any web site today. This brings me to my discovery.

I have been working on a project and my clients most recent request has been to eliminate page refreshes due to post-backs. Of course I said no problem and went about the process of using the ICallbackEventHandler interface to utilize what .NET has provided. To do this requires the writing of many JavaScript functions, which almost all need some reference to one or more controls on the UI. No big deal you say. That's what I said when I started this process. Then I realized that all of the controls have a an ID on the server and an ID on the client side which are different. The problem arose when I needed to reference a text field called "UserID". In the C# code its no problem getting to this object but client side, the "document.getElementById('UserID')" was not returning anything but null.

It took very little time to figure out why this was happening. The control emit a unique id to the client to make sure that all controls are unique. So my "UserID" control ended up with an ID of "ctl00_ctl00_PageContent_Content_UserID". Once I determined this it was easy for the "document.getElementById()" to find the proper control. The only problem was that I was going to have to render every page to find out what the final ID was going to be for each control and if anything changed to alter the hierarchy then that meant the IDs could change.

I was having a field day complaining about why Microsoft would do this and how I was going to create an affective way to handle this. I went through a few different ideas before realizing that all of the control are nested and could be traversed.

I then decided that since I have a master page, that all pages were using, I could use code in the master page to find all controls on any page that used it. Since I know about all of the controls before the page gets rendered, why not emit some JavaScript to reference all of the controls.

First I declared an ArrayList to hold some info:

ArrayList jsControls = new ArrayList();

Then I added some code to my Master Pages "Page_Load" event handler:

this.loadJsControls( this.Page );
jsControls.Sort();
this.Page.ClientScript.RegisterStartupScript(
this.Page.GetType(),
"vars",
string.Join( "", ((string[])jsControls.ToArray(typeof(string)))),
true );

This calls a custom recursive function that loads the ArrayList:

private void loadJsControls( Control control ) {

if ( control is HtmlImage || control is HtmlInputControl ||
control is HtmlContainerControl || control is WebControl ) {

if ( control.ID != null && control.ID.Length > 0 &&
!control.ID.StartsWith( "Image" ) &&
control.ClientID != null &&
control.ClientID.Length > 0 ) {

jsControls.Add(
"var " + control.ID +
" = document.getElementById( \"" +
control.ClientID + "\" );\n" );
}
}

for ( int i = 0; i < control.Controls.Count; i++ ) {
loadJsControls( control.Controls[ i ] );
}
}

Here is an example of the results produced by this:

<script type="text/javascript">
<!--
var changePAsswordLink = document.getElementById(
"ctl00_ctl00_PageContent_header_ctl13_changePAsswordLink" );
var closeLink = document.getElementById(
"ctl00_ctl00_PageContent_header_ctl13_closeLink" );
var exportLink = document.getElementById(
"ctl00_ctl00_PageContent_header_ctl13_exportLink" );
var UserID = document.getElementById(
"ctl00_ctl00_PageContent_Content_UserID" );
// -->
</script>

This allows my JavaScript to not need to look up the control but only know the server side name. Here is an example:

UserID.value = "Joe Blow";

This is possible due to the fact that the JavaScript declarations happen after the page loads so each one already points to the proper control.

I hope this will at least help one other developer.