November 8, 2011

OracleCommand and parameterized update statements

Filed under: Development,Oracle,RADE — Tags: , , , , — Darrin Maidlow @ 4:07 pm

This week I encountered an irritating situation with Oracle while working on code in the application logic.  In a nutshell I am building dynamically created parameterized insert and update statements based on the RADE metadata and the values entered by the user.  The first call InsertNewRecord works perfectly.  The next call UpdateExistingRecord however was not.  The parameterized SQL was being created.  The parameters were being created and assigned to the .  The ExecuteNonQuery() call was executing without returning an error.  Oracle just would not update.   Even more frustrating – this “just worked” in SQL server.

What were the differences?

The basic logic for insert was this (parts omitted because you probably just don’t care):

  1. Get table metadata
  2. Loop through fields in table
  3. for each field retrieve the value from the UI
  4. Add field to parameterized SQL statement with placeholder
  5. Create new parameter with appropriate name and value.   Add parameter to collection
  6. Loop through parameters in the collection and add to the DbCommand
  7. Finally execute the parameterized SQL statement

As I mentioned this worked great.  Fields were inserted and there was much rejoicing.

The logic for an update was similar but there was one big difference:

  1. Get Table
  2. Loop through fields in table
  3. for each field retrieve the value from the UI
  4. If the field is a key add the placeholder to the where condition, otherwise add the field name and value to the update fields part of the SQL
  5. Create new parameter with appropriate name and value.  Add parameter to collection
  6. Loop through parameters in the collection and add to the DbCommand
  7. Finally execute the parameterized SQL statement.

The branch in step 4 and the if statement ended up causing the problem.

The Problem

defaults to “bind by order” – making the order in which the parameters exist in the SQL statement match the order in which the parameters are added to the OracleCommand. This was happening during the insert because of the structure of an insert statement being so linear. However in the update statement I was building the SQL in a more dynamic way. I was maintaining a list field=value conditions and a separate where condition. In the ended up merging them :

   1: String parameterizedSQL = "UPDATE " + table.Name + " SET " + updateStatement + " WHERE " + whereStatement;

So unless my key field( s) all lined up at the end of the table metadata definitions,  appending that where condition at the end my parameter order got all out of whack in the DbCommand.  So my where condition was actually being set to the wrong value – which could have resulted in the wrong records being updated. Nasty.   Fortunately this can be resolved.

The Fix – BindByName=true

To correct this I had to set the Oracle specific BindByName property to true.  (btw this being the default behavior is just silly.  All the other big data providers default to bind by name and Oracle should too.  That’s a rant for another day though.)   My initial solution was to check if the command is an OracleCommand and if found do a little casting to set the BindByName property then recast it back to DbCommand before executing the query.  Constructive feedback is always welcome!

   1: /// <summary>
   2: /// Execute the parameterized query
   3: /// </summary>
   4: /// <param name="conn">open and active DbConnection</param>
   5: /// <param name="trans">Active DbTransaction</param>
   6: /// <param name="parameterizedSQL">the parameterized SQL</param>
   7: /// <param name="paramList">List of OledDbParameter</param>
   8: /// <returns>DataTable containing the results</returns>
   9: public static void RunParameterizedInsertUpdate(DbConnection conn, DbTransaction trans, String parameterizedSQL, List<DbParameter> paramList)
  10: {
  11:     //create the db command and set the parameterized SQL as a property
  12:     DbCommand command = conn.CreateCommand();
  13:     if(trans != null)
  14:     {
  15:         command.Transaction = trans;
  16:     }
  17:     //hack attack!  By default, Oracle requires its parameters to be placed into the command
  18:     //in the order the parameters appear in the parameterized SQL.  Little hackery here
  19:     //to set the Oracle Command to bind by name
  20:     if (command is Oracle.DataAccess.Client.OracleCommand)
  21:     {
  22:         OracleCommand oraCmd = (OracleCommand) command;
  23:         oraCmd.BindByName = true;
  24:         command = oraCmd;
  25:     }
  26:     command.CommandText = parameterizedSQL;
  27:     command.CommandType = CommandType.Text;
  28:  
  29:     //loop through the params and add them to the command
  30:     foreach (DbParameter parameter in paramList)
  31:     {
  32:         command.Parameters.Add(parameter);
  33:     }
  34:     try
  35:     {
  36:         command.Prepare();
  37:         command.ExecuteNonQuery();
  38:     }
  39:     catch (Exception ex)
  40:     {
  41:         command.Dispose();
  42:         throw;
  43:     }
  44: }

September 15, 2010

Mapguide Enterprise 2011 – Fusion and Selection XML

Filed under: Mapguide,RADE — Tags: , , — Darrin Maidlow @ 3:00 pm

I’ve been working to migrate the  Mapguide 2010 code to work with 2011.  In 2010, I only implemented support for the DWF and Ajax viewer.  With the release of 2011, the new  ability to include mapping data from Google, Yahoo and Microsoft in Fusion are huge so I opted to migrate everything over.  The DWF viewer is already deprecated and I suspect the Ajax viewer will likely go next.

With 2010 and the Ajax viewer we had to get the selection from the MapFrame using the GetSelectionXML() method.  Then we had to encode, and send this value up to the web tier for processing.  I had all kinds of business logic that I was hoping to re-use with a minimal amount of modifications so I was trying to find how to recreate this functionality with Fusion.  I figured out how the selections worked on the client side using the new callback system and was getting the selection object – but I could not find anything definitively saying “There is no selection XML on the client side anymore”.    So…

There is no selection XML on the client side any more when using Fusion.

There I said it.  It makes sense too – first getting this large XML string and sending it up was a pain in the ass.  Encoding it, creating a form to submit it, etc.   I should have clued into this sooner – Fusion is updating the selection on the server side as needed. 

So in order to minimally impact the existing code – I added an additional check to some of the calls that looks a little something like this:

   1: if (String.IsNullOrEmpty(selectionXml))
   2: {
   3:     MgResourceService resSvc = (MgResourceService)siteConn.CreateService(MgServiceType.ResourceService);
   4:     sel.Open(resSvc, map.GetName());
   5:     selectionXml = sel.ToXml();
   6: }

Those four lines of code are a lot easier than all the screwing around needed in 2010 to get the selection XML.   With that small modification my existing code is working perfectly!

hope this helps someone =)

July 24, 2010

Creating .NET objects for Mapguide Enterprise 2011

Filed under: Development,Mapguide,RADE — Tags: , — Darrin Maidlow @ 11:15 pm

Better late than never…  I’ve updated my Mapguide Enterprise .NET objects to work with 2011.  The steps in my   have been modernized and simplified significantly.   This post will show you how to create (or re-create) these objects for the 2011 release of Mapguide.  Sorry for skipping 2010 =)

First, download the actual non-aplha release of and extract it.  You will need to have .NET 3.5 installed to run LINQ to XSD.  The project itself is a Visual Studio 2010, .NET 4.0 project.  You should be able to change it to .NET 3.5 with no problems.  I’m not sure about using .NET 2.0.   I still assume these steps should work with Mapguide Open Source 2.2 given its pretty much the same thing as MGE 2011.  Please let me know if you try it and that is not the case.

Building the classes

Last time around we had to mess around with Visual Studio projects, building temporary code, finding and extracting that code from temporary files.  This time around, we’re given a nice little executable that can be run in a batch file.   I’ve posted a copy of my batch file below but it was simply made using a dir /b > CreateMapguideNetObjects.cmd in the Mapguide server schema folder (which by default is to c:\Program Files\Autodesk\MapGuideEnterprise2011\Server\Schema) .  I then edited that file with a text editor that support macros and removed the following schema files:

  • FdoProviderCapabilities-1.0.0.xsd
  • LoadProcedure-1.0.0.xsd
  • LoadProcedure-1.1.0.xsd
  • LayerDefinition-1.0.0.xsd
  • LayerDefinition-1.1.0.xsd
  • LayerDefinition-1.2.0.xsd
  • SiteInformation-1.0.0.xsd
  • SiteVersion-1.0.0.xsd
  • SymbolDefinition-1.0.0.xsd
  • WebLayout-1.0.0.xsd

These files are deprecated object definitions from previous Mapguide releases.  In the end each line in the batch file looks a little like this:

LinqToXsd ApplicationDefinition-1.0.0.xsd /filename:ApplicationDefinition.cs

Executing the batch file will create a number of C# files containing appropriately named classes.

Setting up your project

At this point you should be able to fire up Visual Studio and create a new C# project.   If you have an existing project from a previous version of Mapguide its good to start fresh.  Also, don’t try this in an existing solution that is dependant on the project that contains the Mapguide objects.  This will just result in a bunch of extra screwing around to avoid compiler errors from missing code during the process.    This time around its a lot easier.  Create a new DLL project.  Add a reference to the Xml.Schema.Linq.dll file that was included with LinqToXsd.exe.   Add a reference to the following Mapguide dlls:

  • OSGeo.Mapguide.Foundation
  • OSGeo.Mapguide.Geometry
  • OSGeo.Mapguide.MapguideCommon
  • OSGeo.Mapguide.PlatformBase
  • OSGeo.Mapguide.Web

You’ll also need to ensure that the appropriate unmanaged assemblies are available in the calling applications bin folder when you go to run this stuff. 

Next place all of the generated C# files in the new project.  Once you build you’re going to see a ton of errors.  We’ll clean those up.

To resolve a lot of these errors I did a global search and replace on “global::” and replaced it with nothing.  Also, I wrapped each class in a unique wrapper classes to prevent duplicate type errors.  Finally, the case issue with DataType was still an issue – and I resolved it by changing the case on DataType to be Datatype:

   1: public string DataType {
   2: public string Datatype {

For a complete view of the changes I made do a file compare between the code in the attached zip file and your newly generated code.

<insert 3 week gap here, wherein I had so that I could actually test this newly created code, oh and I also went on vacation for a few days too =)/>

And back.  The best part about this is that it seems ALL my old code just worked with upgraded basic layouts after changing it to look for the object definitions within the new wrapper classes.   Now I just need to add support for flexible layouts and we’ll be laughing.

The Code

Please note – I didn’t rebase the code.  It’s all in the RADE.MGE namespace.  If you would like to use it, feel free to re-base it – or just leave it as is.  Also, if you create any unit tests or enhancements and would like to share them – please feel free!  

As I update the project myself, or receive updates I will update this file.

Finally, the will still work with this new project.  Perhaps one day, I’ll post some fancy new code in C# =)

Hope this comes in handy, I welcome your comments.

July 19, 2008

RADE Milestone – Object Relational Mapping with NHibernate

Filed under: RADE — Tags: , — Darrin Maidlow @ 3:37 am

It’s 1:30AM, I guess it’s Saturday now. =)  I’ve been furiously pounding away for the past two weeks building a new for RADE 4.0.  Gotta love 12 – 18 hour days for two weeks (Good thing I love software development).  My wife is away for the week, so I can continue working these stupid hours for another week.  Anyhow I’ve chosen to proceed with for the time being.  with the looks really cool and I’ve used it for some small research/test projects recently, but with the lack of support for database other than SQL server – it’s not an option at this time.

NHibernate was a tough curve for me.  Initially, I started testing code generators.  After spending a significant amount of time reading, testing, and pulling out hair I came to the conclusion that .  From my experiences is probably the best code generator out there right now – but its still lacking in some areas.  More importantly however, I learned that code generation is not a good place to start when implementing NHibernate for the first time.  There is so much going on under the hood – in my opinion you need to start off doing a reasonable size project by hand.  Code generation has significant benefits, because the generated code is so similar with simple replacements it just makes a lot of sense once you wrap your head around what’s going on with NHibernate.

As per my when implementing nHibernate by hand, .  Just the other day I found a *great* ReSharper .  When editing NHibernate HBM XML files, it does a bunch of validation right in the editor.  Saves you a lot of time finding problems without having to actually run a unit test and debug sometimes cryptic error messages.

I bought a copy of NHibernate In Action.  I would recommend this book to you only if you have no experience, or understanding of Object Relational Mappers.  As the book stands right now, it’s not really a good developer reference and only covers really basic examples.  The documents that helped me the most to get everything up and running was .  The NHibernate documentation is pretty cryptic.  Don’t read this stuff 12 hours into your day.  No amount of RedBull will give you the focus needed to make sense of it.  In the first 8 hours of the day, its quite helpful.

I primarily work in VB.NET.  For this project however, I switched to C#.  Maybe now, the my colleagues at will stop giving me a hard time =).  Seriously though.  Examples are a LOT easier to come by in C#, probably 10:1.

Finally, get NUnit running.  I had a lot of problems using the built in Microsoft Test projects with NHibernate – so I’ll be sticking with NUnit. If you’ve never done unit testing (you know who you are) do it.  Particularly in this case – its crucial.  You (Again you know who you are =]) used to write simple winform apps, and put a bunch of buttons on them.  Don’t do that. 

So, if you are one of the RADE non-developer users and you read on this far.  Congrats.  This milestone will not directly help you with your use of RADE.  However, it’s a large step forward for the underlying architecture – and you will benefit from that. 

Well back to Visual Studio I go..

Technorati Tags: ,,,

June 29, 2008

RADE – Build custom web applications, without writing custom code

Filed under: RADE — Tags: — Darrin Maidlow @ 7:21 am

In response to numerous queries, I put together this post to help answer the question – what is RADE (formerly known as WebRADE). RADE is a development framework that delivers custom web applications using existing data without having to write a single line of code.  RADE provides a rich set of functions including security, prompting queries, configurable reports and charting using existing database and mapping data, without the need for expensive consultants and programmers.

RADE includes a configurable web mapping interface that incorporates queries, reports, charts and basic editing tools. These “components” work with the data you have stored in one or more databases (Oracle, SQL Server, Access) and can be used by any application made with RADE. Right now RADE supports MapGuide 6.x, we are in the process however of extending the mapping interface to allow RADE applications to use multiple web mapping engines including MapGuide 6.x, MapGuide Enterprise 2009 / Mapguide Open Source 2.0 and Google Maps. Other mapping engines may be implemented in the future.  

An application made with RADE is a collection of queries, reports, charts, and of course users/groups managed by the integrated RADE security model. They are your custom solutions founded upon the bedrock that RADE provides.

A user with basic knowledge of their underlying database structure can design customized queries, reports, and charts in a matter of hours. Solutions can be as broad or as narrow as needed depending on the requirements of the organization. All of this work is done using RADE’s web-based administration tools.  

Before RADE, I worked for a provider of customizable desktop GIS, automated map standardization, and facilities management solutions for both government and industry. GIS/Geospatial implementations involved a lot of customized work, specific to particular clients, and could seldom be easily reused. This is when and where I came to realize that there had to be a better way to develop solutions.  

As RADE developed, we put it to the test and have been developing a series of standalone applications build on its framework. With RADE, we are saving time on projects which results in significant cost savings and rapid delivery for our clients.  

Out of curiosity one day, I connected RADE to my accounting and bug-tracking databases just to see what would happen. With a little research into the underlying databases — I was able to create both queries and reports on both data sources. No map required.  

As a developer I have projects that require me to extend RADE with more proprietary code. Take for example. FloorView is a complete vertical application built on top of RADE. It uses the RADE security/authentication system in addition to the RADE queries and reports — but is in itself a full application. This allowed us to leverage the existing functionality saving time, and money. In addition to this, FloorView appears as a RADE application when authorized users login to the site keeping all of the RADE based applications in one convenient location.  

In addition to FloorView a number of other vertical applications have been developed on top of, or using RADE. They include solutions for address management, disaster planning and recovery, sexual predator and offender tracking, crime mapping and analysis, oil and gas lease management and service request tracking and management.  

The best analogy I have for RADE is “Developer in a Box”.  Much of the work is already done for you…

Powered by WordPress

Switch to our mobile site