Executing OLEDB SQL statement from C#

Here is a way to execute a sql statement that returns one column of one row. If there is more than one row returned, it will return nothing.

        public static string CreateReader(string connectionString, string queryString)
        {
            string result="";
            int rowCount = 0;
            using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(connectionString))
            {
                System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand(queryString, connection);
                connection.Open();
                System.Data.OleDb.OleDbDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    rowCount = rowCount + 1;
                    result = reader[0].ToString();
                }
                reader.Close();
                return (rowCount == 0 || rowCount > 1) ? "" : result;
            }
        }

WCF Intermediaries with Binding Switching

I have been working on a WCF intermediary that receives messages from a 3rd party and routes this onto another WCF service. The intermediary service uses basicHttpBinding whereas the destination service is netTcpBinding. I have worked on similar patterns before, but they always had the same binding on each service and they worked well, therefore I hadn’t anticipated any problems.


However, once I had this all set-up I started receiving the following error on the intermediary service: “Addressing Version ‘AddressingNone (http://schemas.microsoft.com/ws/2005/05/addressing/none)’ does not support adding WS-Addressing headers.”


This error appears to stem from the fact that basicHttpBinding is using SOAP 1.1 for the message version and no WS-Addressing, whereas netTcpBinding is using SOAP 1.2 for the message version with WS-Addressing. I had originally attempted to use custom bindings to get over this hurdle without much success so adopted to implement a message conversion in the intermediary service instead.


Your typical intermediary service would tend to have a service contract that is defined as so:


[ServiceContract]


public interface IMyIntermediaryService


{


   [OperationContract(


      IsOneWay = false,


      IsInitiating = true,


      IsTerminating = false,


      Action = “*”,


      ReplyAction = “*”)]


   [FaultContract(


      typeof(MyCustomFault),


      Namespace = “http://mydomain.com/myapplication/2009/08”)]


  


   Message ProcessMessage(Message message);


}


The implementation of the ProcessMessage method would be something like the following. Note that this is a very basic example to be succinct, you would need to include error handling etc. In addition we are defining the destination endpoint in the web.config using the name “destination” as the identifier.


public Message ProcessMessage(Message message)


{


   var channelFactory = new ChannelFactory<IMyIntermediaryService>(“destination”);


 


   IMyIntermediaryService forwardingChannel = channelFactory.CreateChannel();


 


   Message responseMessage = forwardingChannel.ProcessMessage(message);


   channelFactory.Close();


 


   return responseMessage;


}


Now, in order to handle the message conversion you would supplement the above code so that it identifies the message version received. Note that we are solely checking for netTcpBinding here, but this code could be modified to expand upon this to make it more generic.


public Message ProcessMessage(Message message)


{


   // Get the message version


   MessageVersion returnMessageVersion = message.Version;


   bool messageConverted = false;


 


   var channelFactory = new ChannelFactory<IMyIntermediaryService>(“destination”);


 


   IMyIntermediaryService forwardingChannel = channelFactory.CreateChannel(); 


 


   // If we are using NetTcpBinding make sure that the message we are sending is


   // Soap 1.2 WS-Addressing if it is not already


   if (channelFactory.Endpoint.Binding.GetType() == typeof(NetTcpBinding)


       && message.Version != MessageVersion.Soap12WSAddressing10)


   {


      message = CreateMessageCopy(message, MessageVersion.Soap12WSAddressing10);


      messageConverted = true;


   }


 


   Message responseMessage = forwardingChannel.ProcessMessage(message);


   channelFactory.Close();


 


   // Convert the message type back to that of the original if necessary


   if (messageConverted)


   {


      responseMessage = CreateMessageCopy(responseMessage, returnMessageVersion);


   }


   return responseMessage;


}


Note that you must also covert the result back to the original format if a conversion has taken place otherwise the client will throw an exception “An error occurred while receiving the HTTP response to http://myserver/myservice.svc. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.”


The conversion method would be something like the following


private static Message CreateMessageCopy(


   Message message,


   MessageVersion newMessageVersion)


{


   Message copy = Message.CreateMessage(


      newMessageVersion,


      message.Headers.Action,


      message.GetReaderAtBodyContents());


   copy.Properties.CopyProperties(message.Properties);


   return copy;


}

Selecting all rows from a stored procedure

I needed to use a select to return data, however the data resided via a call to a stored procedure.

For a simple example, I will use the the following stored procedure

exec sp_who 'sa'

So how do I select * from a stored a procedure?

Use OPENROWSET

select *
from openrowset('sqloledb','Server=(local);TRUSTED_CONNECTION=YES','set fmtonly off exec master.sys.sp_who ''sa''')

which returns this result

Which means that I can filter what I want:

select *
from openrowset('sqloledb','Server=(local);TRUSTED_CONNECTION=YES','set fmtonly off exec master.sys.sp_who ''sa''') [x]
where x.status='sleeping'

Castle Windsor and non-HTTP Protocol WCF Services

I had been working quite happily with Castle Windsor and WCF services using WCF Facility when implemented through an HTTP binding of some description. You simply hook in the DefaultServiceHostFactory from Castle.Facilities.WcfIntegration into your ServiceHost declaration such as the following example:


<%@ ServiceHost Language=”C#” Debug=”true” Service=”MyService” CodeBehind=”MyService.svc.cs”


Factory=”Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration” %>


You would then register the WindsorContainer within the Application_Start event of your Global.asax like so or however you prefer register your components, the point being it is done in the Application_Start event.


protected void Application_Start(object sender, EventArgs e)


{


   var container = new WindsorContainer(“ioc.config”);


   DefaultServiceHostFactory.RegisterContainer(container.Kernel);


}


However, let’s say you are binding to net.tcp and hosting in WAS (Windows Process Activation Service)? This event will not get called, so you need to find another way to initialise your Castle Windsor container.


I confess I spent a while looking at the Host Factory in more detail, looking to wrap the DefaultServiceHostFactory. However, there appears to be a far simpler solution and that is to make use of the little documented AppInitialize method. If you create a class (any class), put it into the ASP.NET App_Code folder in your project and give it a method signature as defined below, this little baby will get fired exactly when you want it to. You can then initialise your IoC container in there.


public class InitialiseService


{


   /// <summary>


   /// Application initialisation method where we register our IOC container.


   /// </summary>


   public static void AppInitialize()


   {


      var container = new WindsorContainer(“ioc.config”);


      DefaultServiceHostFactory.RegisterContainer(container.Kernel);


   }

}

Our offer still stands and you know where to find us…

I talked about the results of a benchmarking study performed by Greg Leake a couple months back on my blog. Greg took a hard look at Windows Server 2008 and the .NET Framework 3.5 in comparison to IBM’s Power6 and WebSphere 7 from both a cost and performance standpoint. The results  show that customers can save up to  81% in total system costs  by running applications on Windows Server 2008 rather than IBM WebSphere 7 on Power6/AIX.  The study also shows that Power6 customers who switch to Windows Server 2008, but continue to use WebSphere, could save up to 66%. What’s more, these cost cutting measures do not come at the sacrifice of performance; customers could see an increase in performance up to 57% by employing .NET Framework and/or Windows Server 2008.


 


Why do I bring this up again? Well, we’re not done putting our platform to the test! Recently, we discovered that IBM quietly published their own benchmarking results to attempt to invalidate our original results. This provides us with yet another opportunity to make some comparisons, and bring them out to our collective customers in a public forum. The outcome – we stand by our previously published results and my earlier invitation stands to have IBM to meet us in an independent lab to perform additional testing of the .NET StockTrader and WSTest benchmark workloads and pricing analysis of the middle tier application servers tested in our benchmark report.


 


I guess the only thing I’m left wondering about is who will love Windows next?