Wednesday, October 28, 2009

Visual Studio 2010 and .NET 4.0 Series – Code Contracts

I had written a couple of days ago on my blog about the release of VS2010 and .NET 4 Beta 2. Now that I have had a chance to install and play around a bit, I am hoping to explore some of the new features of .NET 4 and VS 2010 in the next few weeks. I will kick off this week with Code Contracts.

According to MSDN, “Code contracts provide a way to specify preconditions, postconditions, and object invariants in your code”. To work with code contracts .NET 4 now comes with a new namespace System.Diagnostics.Contracts.

As mentioned in the above definition, code contracts can be used to check, pre-conditions, post-conditions and invariants. Pre-conditions are conditions that should be satisfied before a method is invoked; post-conditions are conditions that should be met just before the method finishes execution and invariants validate class state. We will look at Pre-Conditions with an example and a peek into Post Conditions in this post. I will finish this off with another post on Post Conditions example and invariants.

Preconditions

The Contract.Requires method can be used to validate preconditions. An example of this will be to validate parameters that are being passed into a method. To demonstrate this, I will create a new console project and write the code below.

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: using System.Diagnostics.Contracts;
   7:  
   8: namespace CodeContractsSample
   9: {
  10:     class Program
  11:     {
  12:         static void Main(string[] args)
  13:         {
  14:             Concatenate(String.Empty, "test");
  15:             Console.ReadLine();
  16:         }
  17:  
  18:         static void Concatenate(string leadingstring, string trailingstring)
  19:         {
  20:             Contract.Requires(leadingstring.Length > 0, "Ensure leading string is valid.");
  21:             Console.WriteLine(String.Concat(leadingstring,trailingstring));
  22:  
  23:         }
  24:     }
  25: }




Let us harp a bit on the Contract.Requires method. The method takes two parameters; the first is a boolean condition that needs to be enforced. The second optional parameter is the message that needs to be displayed if the condition evaluates to false. In the above example, the method makes sure the leading string is not empty.

When I wrote this code and ran it, I found it to my surprise that the contracts were not working. After a bit of research, I found that for contracts to work, you need an additional download. You can find the download at Dev Labs. Once you download and run the installer, you will find an additional tab called Contracts in your solution properties as shown below.

CodeContracts

You can then control how your contracts work in this window. Please note that to without Team System you can do only runtime checking. Running the application now throws the designated message if we pass an empty string to the Concatenate method.

A variant of this is the Requires<> method which takes a generic TException parameter. Below is the code to raise an exception and catch it in code. One thing you have to make sure is you turn off the assert on contract failure setting in the Code Contracts settings tab. This will ensure exceptions are raised from the contracts.



   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5:  
   6: using System.Diagnostics.Contracts;
   7:  
   8: namespace CodeContractsSample
   9: {
  10:     class Program
  11:     {
  12:         static void Main(string[] args)
  13:         {
  14:             try
  15:             {
  16:                 Concatenate(String.Empty, "test");
  17:                 
  18:             }
  19:             //catch the argument null exception raised by the contract
  20:             catch(ArgumentNullException nullString)
  21:             {
  22:                 Console.WriteLine(nullString.Message);
  23:             }
  24:             Console.ReadLine();
  25:         }
  26:  
  27:         static void Concatenate(string leadingstring, string trailingstring)
  28:         {
  29:  
  30:             //raise an exception if the contract fails
  31:             Contract.Requires<ArgumentNullException>(leadingstring.Length > 0);
  32:             Console.WriteLine(String.Concat(leadingstring, trailingstring));
  33:  
  34:         }
  35:     }
  36: }


PostConditions


Though most of the basic concepts are the same for post and preconditions, postconditions offer a bit more flexibility and features that preconditions do not. Postconditions are validated by using the Contract.Ensures method. Postconditions also offer the following capabilities


  • Ability to refer the return value of a method using Contract.Result<T> where T should be of the same type as the return type of the method. Obviously you cannot use Result for methods that do not return anything.

  • Ability to check the value of a variable at the beginning of the method. This can be done by using Contract.OldValue<T>(e) where e is the variable for which you want the old value and T is the type of that variable.

  • Ability to ensure a condition is met when an error is thrown in the method. You can use the Contract.EnsuresonThrow<>.

That is it for this post. I will show you in my next post how to write PostConditions and we will also look at invariants.

Monday, October 19, 2009

Visual Studio 2010 and .NET 4.0 Beta 2 now available

Technorati Tags: ,,,

 

Microsoft made available today the beta 2 of VS2010 and .NET 4.0. It is available for MSDN Subscribers on the 19th and its general availability is from the 21st of October. You can download the beta 2 from https://msdn.microsoft.com/en-us/subscriptions/securedownloads/default.aspx?pv=18%3a370

Apart from bug fixes the Beta 2 also is supposed to have templates for Sharepoint solutions and Azure. More details on Somasegar’s blog http://blogs.msdn.com/somasegar/

I will write more on VS 2010 when I have had a chance to play with it.

Sunday, October 4, 2009

Using Table Value Parameters in SQL Server 2008

Table-valued parameter is another exciting new feature in SQL Server 2008. Essentially, TVP solves the problem of inserting multiple rows into the database. Various solutions have been implemented to achieve this, ranging from round trips for every row to comma separated values. With TVP, you can insert multiple rows with a single round trip to the server without having the additional overheads of composition and de-composition of values.

TVP is not entirely new to SQL Server. SQL Server 2000 introduced the table variables which can be used to store a set of records. Where TVP builds on it, is the ability to pass them as input parameters to stored procedures or functions. This could not be done with table variables.

Let us look at some of the features of TVP before we see how they can be used to insert data.

  • TVPs can participate in Set based operations.
  • They are strongly typed
  • You cannot perform DML operations on TVPs. They can be passed as only READ-ONLY parameters to stored procedures\functions
  • Remember that TVPs are materialized in the TempDB. Essentially, it means that if you insert more rows into your TVP, the size of TempDB is what gets affected.

Having seen what TVP is, let us now move onto build an example which will actually use TVP. Here, I will show you a very common scenario that we use for multiple entries. We have an order and each order is comprised of multiple products. I have created the necessary tables using the scripts below

   1: Create table dbo.Products



   2: (



   3: ProductId int IDENTITY(1,1) PRIMARY KEY,



   4: ProductName varchar(250),



   5: ItemRate decimal



   6: )



   7:  



   8: Create table dbo.Orders



   9: (



  10:     OrderId int IDENTITY(1,1) Primary key,



  11:     OrderDate datetime,



  12:     OrderStatus int



  13: )



  14:  



  15: Create Table dbo.OrderDetails



  16: (



  17:     OrderId int Foreign Key references Orders(OrderId),



  18:     ProductId int Foreign Key references Products(ProductId),



  19:     Quantity int,



  20:     Amount decimal



  21: )




I have also inserted data for the tables above. The next thing to do is to create a user defined type that will insert data into the OrderDetails table.





   1: Create type dbo.OrderParam as Table



   2: (ProductId int, Quantity int, Amount decimal)








Now that the type has been created, let me go ahead and create a stored procedure that takes the just created type as an input parameter.





   1: Create proc dbo.InsertOrders



   2: @OrderItems OrderParam ReadOnly



   3: as



   4: begin



   5:     Declare @iOrderId int



   6:     Insert into Orders values (GETDATE(),0)



   7:     Select @iOrderId=SCOPE_IDENTITY()



   8:     Insert into OrderDetails(OrderId, ProductId, Quantity, Amount)



   9:         Select @iOrderId, ProductId, Quantity, Amount from @OrderItems



  10: end




Notice the fact that the TVPs have been declared read only. Also pay attention to the second insert statement. The values are inserted from the input parameter using a single select statement. The only remaining thing to do is to call this stored procedure from the front end.



For this purpose, I have created a data grid where users select the orders and save it into the database. Below is the code that goes into the Save Click routine.





   1: private void SaveButton_Click(object sender, EventArgs e)



   2:         {



   3:             //create a new datatable to hold the grid data



   4:             DataTable OrderParam = new DataTable();



   5:             //the columns are the same as the TVP type



   6:             OrderParam.Columns.Add("ProductId", typeof(int));



   7:             OrderParam.Columns.Add("Quantity", typeof(int));



   8:             OrderParam.Columns.Add("Amount", typeof(decimal));



   9:  



  10:  



  11:             //loop through the grid to load data into the datatable



  12:             foreach (DataGridViewRow item in grdOrders.Rows)



  13:             {



  14:                 DataGridViewComboBoxCell prodCell = (DataGridViewComboBoxCell) item.Cells[0];



  15:                 if (prodCell.Value != null)



  16:                 {



  17:                     DataRow prdRow = OrderParam.NewRow();



  18:                     prdRow[0] = prodCell.Value;



  19:                     prdRow[1] = item.Cells[1].Value;



  20:                     prdRow[2] = item.Cells[2].Value;



  21:                     OrderParam.Rows.Add(prdRow);



  22:                 }



  23:             }



  24:             //connect to the database to insert the values.



  25:             var connString = ConfigurationManager.ConnectionStrings["DatabaseConn"].ConnectionString;



  26:             SqlConnection dbConn = new SqlConnection(connString);



  27:             dbConn.Open();



  28:             using(SqlCommand cmd = new SqlCommand("InsertOrders", dbConn))



  29:             {



  30:               cmd.CommandType = CommandType.StoredProcedure;



  31:               cmd.Parameters.AddWithValue("OrderItems", OrderParam);



  32:               cmd.ExecuteNonQuery();



  33:             }



  34:             dbConn.Close();



  35:         }




The only thing worth noticing is that I have used a datatable which is quite logical because TVPs are tables anyways. As you can see, the savings in the number of round trips to the database is enormous. The USP of the TVPs lie in the fact that they are not hard to implement at all.  Have fun!!!

Friday, October 2, 2009

Time well SpEnt

Technorati Tags: ,,

When a relatively unheard of theatre group comes forward to do a quiz, you are not sure what to expect. But ASAP did themselves only favours, be it the quiz or the short sketch they showcased just before the finals. The only disappointing thing for the evening was the number of teams participating. The quiz master put the number at 100 which seemed a bit low given that Chennai usually attracts a lot of participation.

The quiz kicked off with 40 question prelims which seems to be the standard nowadays. It fittingly started with a question on the Bapu.

There were questions on Anjali Tendulkar, the Olympics and Quick Gun Murugan. The toughest one seemed to be on the longest winning streak in sports history. I don’t think any of the 100 odd teams got this right. 8 teams qualified for the finals at the end of a low scoring prelims with  “When I was in London” comprising of Srinivasan and Rajagopal coming out tops.

The questions in the finals were engrossing bringing out some brilliant answers from the teams. The quality of quizzing was again top-class. JK and Sriram were quick off the blocks but the team of V.V. Ramanan and Ramkumar eventually caught up leading the quiz into the last round. It came down to the last question to decide the winners and “When I was in London” bagged it with a brilliant answer on the word “FAIL”.

Overall a very enjoyable evening. If anything, the finals just seemed to be one round too long but I dont think the ardent quizzers of Chennai would complain given the good quizzing that was in offing. Mention should also go to the quiz master Vinod and his colleague Ganesh for the research and the quality of questions.

I hope that this now goes on to become an annual event and one more annual quiz gets added to the Chennai quizzing calendar. Way to go ASAP!!!