Blue Theme Orange Theme Green Theme Red Theme
 
Team Foundation Server Hosting
Home | Forums | Videos | Advertise | Certifications | Downloads | Blogs | Interviews | Jobs | Beginners | Training
 | Consulting  
Submit an Article Submit a Blog 
 Jump to
Skip Navigation Links
TechnologyExpand Technology
WebsiteExpand Website
Nevron Chart
Search :       Advanced Search »
Home » LINQ » SQL Server Stored procedures and UDF within a LINQ context-Part I

SQL Server Stored procedures and UDF within a LINQ context-Part I

In this two parts particle, I will give techniques of how to deal with stored procedures and user defined functions UDF from within a LINQ context rather than ADO.Net.

Author Rank :
Page Views : 7745
Downloads : 85
Rating :
 Rate it
Level : Intermediate
   Print Read/Post comments Post a comment  Similar Articles  
   Email to a friend  Bookmark  Author's other articles  
Download Files:
Bejaoui.zip
 
 
Discover the top 5 tips for understanding .NET Interop
Become a Sponsor
 Tag Cloud
 Latest Jobs
More ... 
 Latest Interview Questions
More ... 


In this two parts particle, I will give techniques of how to deal with stored procedures and user defined functions UDF from within a LINQ context rather than ADO.Net. The advantage of calling the stored procedures and UDF via LINQ is, in fact, that LINQ is not concerned whether they are written using Transact SQL or SQL Common language Runtime that allows users to create objects such as stored procedures or user defined functions using C# or VB.Net. In the other hand, LINQ enables to write strongly typed queries. To know how to execute a stored procedure or a given UDF using LINQ and have an overview concerning this issue; I invite you to follow those scenarios.

During this tutorial the NorthWind SQL Server data base is used as a data source. In order to download it you can reach it via this link

http://www.microsoft.com/downloads/details.aspx?FamilyID=06616212-0356-46A0-8DA2-EEBC53A68034&displaylang=en

The NORTHWIND.MDF could be reached in your hard drive C:\SQL Server 2000 Sample Databases\NORTHWND.MDF

Before starting let's make a rapid comparison between the stored procedures and the UDF or user defined functions through this schedule:

Stored procedures

 User defined functions

A Stored procedure can't return a table variable in spite of the ability  to create one  A Function can return table variables
A  Stored procedure can change the server environment  A Function can't change the server environment
A Stored procedure can be used in an XML FOR clause  A Function can't be used in an XML FOR clause
Stored procedures are called independently using EXEC  Functions are called from within  SQL statement
Stored procedures may return an integer or nothing  Functions must always return an object
A stored procedure continues to the next instruction when an error occurs except that an error handling code is set  Functions stops execution when an error occurs


In addition to the above schedule, I can say that based on my experience, the stored procedure are more rapidly executed than the user defined functions. 

First, create a new windows Console application then add those namespaces into your project System.Data.Linq; and System.Data.Linq.Mapping. If a reference isn't already added to System.Data.Linq then right click on the project icon in the solution explorer and add a reference to it.


Figure 1


Stored procedures and LINQ

Senario1:

Say that you want to update the NorthWind Products table by enabling final users to modify the price related to a given product according to its identifier. In this case, the user has to enter both the product identifier and the price value via an interface dedicated to that.

This is the stored procedure core:

CREATE PROCEDURE dbo.ModifiyPrice

          (

            @NewPrice  MONEY,

            @ProdID INT

          )

AS

          /* SET NOCOUNT ON */

          UPDATE Products

          SET UnitPrice = @NewPrice

          WHERE ProductID = @ProdID;

RETURN

Let's switch to Visual Studio and perform the code that calls the above procedure. First, you derive a class from the DataContext in order to create some customized behaviors those fit our need.

class NorthWind : DataContext

{

public NorthWind()

    : base(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" +

          @"C:\SQL Server 2000 Sample Databases\NORTHWND.MDF';" +

          @"Integrated Security=True;Connect Timeout=30;User Instance=True") { }

.........

.........

}


Then you add a method responsible of mapping the stored procedure into the above class, it is public int SetNewPrice in this case.

class NorthWind : DataContext

{

//The constuctor

public NorthWind()

: base(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" +

  @"C:\SQL Server 2000 Sample Databases\NORTHWND.MDF';" +

  @"Integrated Security=True;Connect Timeout=30;User Instance=True") { }

//This attribute provides data about the stored procedure that will be used

//through reflection mechnism within the SetNewPrice method

[Function(Name = "ModifiyPrice")]

//The method that maps the stored procedure must return an object

//We use an int as a returned type because this is only an update action

public int SetNewPrice([Parameter(Name="@NewPrice",DbType="int")]int Price,[Parameter(Name="@ProdID",DbType="int")]int identifier)

 

{

/*The ExecuteMethodCall recieves as parameters, a datacontext, a MethodInfo

   therefore System.Reflection namespace has to be included and finally an object

   table that contained the input parapeters entred by the user

   and it returns an IExecuteResult object*/

IExecuteResult oResult = this.ExecuteMethodCall(this, MethodInfo.GetCurrentMethod() as MethodInfo,new object[2]{Price,identifier});

//The IExecuteResult.ReturnValue is a type of object

//therefore it must be transtyped to integer type

return (int)oResult.ReturnValue;

 

}

}

DataContext.ExecuteMethodCall() is used in this case and it returns an IExecuteResult object that returns the executed query result by itself through the oResult.ReturnValue object. It is only a unique update operation to perform in this case, thus, the returned value is not so important in this context rather than the update operation itself. Another important think that has to be said before you begin write the code. In fact, the System.Reflection namespace has to be included as we use MethodInfo in this context. The MethodInfo invokes the method that maps the stored procedure through reflection.

Now, let's write a code that consumes the services of this above class

static void Main(string[] args)

{

    //Initilise a NorthWind object

    NorthWind oNorthWind = new NorthWind();

    //The product identifier

    Console.WriteLine("Enter the product identifier");

    string id = Console.ReadLine();

    //The new price

    Console.WriteLine("Enter the product new price");

    string np = Console.ReadLine();

    //Execute the product update operation through the bellow method

    int oResult = oNorthWind.SetNewPrice(Convert.ToInt32(id), Convert.ToInt32(np));

    Console.WriteLine(string.Format("The product {0} price is updated to {1}",id,np));

    Console.ReadLine();

}

Let's run the application and observe,


Figure 2


Open the products table and the result will be


Figure 3


Senario2:

Always with the same table, I mean Products one. Imagine that the price follow this mechanism



Figure 4


Where C is the periodic growth price ratio multiplied by a constant that depends on whether the price is greater or less than 20, the final price will be the initial one multiplied by the C coefficient.

And this is the new stored procedure core:

ALTER PROCEDURE dbo.ModifiyPrice

          (

            @NewPrice  MONEY,

            @ProdID INT

          )

AS

          /* SET NOCOUNT ON */

         

          IF @NewPrice> 20

           BEGIN

             UPDATE Products

             SET UnitPrice = UnitPrice*(@NewPrice/UnitPrice)*1.1

             WHERE ProductID =@ProdID  

           END

         

          ELSE IF @NewPrice < 20 

     BEGIN

       UPDATE Products

             SET UnitPrice = UnitPrice*(@NewPrice/UnitPrice)*1.5

             WHERE ProductID =@ProdID

     END

In this case, the stored procedure will be mapped according to its multiple results shape. And the code will be changed to fit the new circumstances:

class NorthWind : DataContext

{

//The constuctor

public NorthWind()

: base(@"Data Source=.\SQLEXPRESS;AttachDbFilename=" +

  @"C:\SQL Server 2000 Sample Databases\NORTHWND.MDF';" +

  @"Integrated Security=True;Connect Timeout=30;User Instance=True") { }

 

//This attribute provides data about the stored procedure that will be used

//through reflection mechnism within the SetNewPrice method

 [Function(Name = "dbo.ModifiyPrice")]

//If There is nothing to return set the generic type to int

//As the stored procedure returns and integer 0 after execution

 [ResultType(typeof(int))]

 [ResultType(typeof(int))]

//The method that maps the stored procedure must return an object

//We use an int as a returned type because this is only an update action

 

public IMultipleResults SetNewPrice([Parameter(Name="@ProdID",DbType="int")]int identifier,

     [Parameter(Name = "@NewPrice", DbType = "int")]int newprice)

{

    /*The ExecuteMethodCall recieves as parameters, a datacontext, a MethodInfo

       therefore System.Reflection namespace has to be included and finally an object

       table that contained the input parapeters entred by the user

       and it returns an IExecuteResult object*/

       

     IExecuteResult oResult = this.ExecuteMethodCall(this, MethodInfo.GetCurrentMethod() as MethodInfo,new object[2]{identifier,newprice});

   

    //The IExecuteResult.ReturnValue is a type of object

    //therefore it must be transtyped to integer type

   

     return (IMultipleResults)oResult.ReturnValue;

 

}

}

As you remark, the returned type is changed from int in the first scenario to IMultipleResults in the current one because each block of the stored procedure returns a different result. Hence, you will deal with a multiple queries context. The IMultipleResults interface is leveraged for such case.

In order to make use of the above code, let's implement the main method as follow:

static void Main(string[] args)

{

    //Instanciate the NorthWind data context

    NorthWind oNorthWind = new NorthWind();

    //Enter the product identifier

    Console.WriteLine("Enter the product identifier number");

    string id = Console.ReadLine();

    //Enter the price of the accoring  product

    Console.WriteLine("Enter the new price");

    string price = Console.ReadLine();

  

    try

    {

        //The first block is executed

        if (Convert.ToInt32(price) > 20)

        {

         /* The IMultipleResults represents the queries result, the returned object is not our primary concern, the principal think is to execute the update*/

           

            IMultipleResults result1 = oNorthWind.SetNewPrice(Convert.ToInt32(id), Convert.ToInt32(price));

            Console.WriteLine("The first block of the stored procedure is used");

            Console.WriteLine("Update operation is complete");

            Console.Read();

        }

        //The second bolck is executed

        else

        {

            IMultipleResults result2 = oNorthWind.SetNewPrice(Convert.ToInt32(id), Convert.ToInt32(price));

           

            Console.WriteLine("The second block of the stored procedure is used");

            Console.WriteLine("Update operation is complete");

            Console.Read();

        }

    }

    catch (Exception caught)

    {

        Console.WriteLine(caught.Message);

        Console.Read();

    }

   

}

As you remark, the code is cracked into two main blocks, the first one deals with the situation where the entered price is more than 20 and the second block deals with the situation where the price is less than or equal to 20. For each situation, an IMultipleResults object is returned. Normally, you make use of the result1.GetResult<typeof(returned object)>() and result2.GetResult<typeof(returned object)>() that returns a generic IEnumerable object that enables us to enumerate table objects through a foreach loop, but in this situation there is not important returned objects, I mean the main task is to update the data base through the employed stored procedure and no more. In this case, a simple integer is returned after executing the update operation. Thus, you have to precise that the type of the result is integer through adorning the IMultipleResults SetNewPrice() method that returns results by the both attributes [ResultType(typeof(int))] and [ResultType(typeof(int))], those last ones are very necessary even there are not returned objects; if you ignore them you'll receive an Invalid operation exception at the run time.

Finally, try to run the application and observe:


Open the products table 


Figure 5


As you remark, the initial price is 20. Try to modify the price as follow:

 
Figure 6


The new price will be leveraged according to the first alternative as the price is more than 20 and the result will be as below after reopening the Products table.


Figure 7


Now, set back the unit price to its initial value, I mean, the unit price of the product 1 to 20. Then run the application and try to update the same product using a price value less than or equal to 20.


Figure 8


The result will be leveraged according to the second alternative


Figure 9

Finally, recall that LINQ provides more than one mechanism to call a stored procedure. In The part II of this article you'll discover how to call an UDF and obtain its result(s) using LINQ.


Good Dotneting!!!

Comment Request!
Thank you for reading this post. Please post your feedback, question, or comments about this post Here.
Login to add your contents and source code to this article
 [Top] Rate this article
 
 About the author
 
Bechir Bejaoui

The author holds a master degree in NTIC specialized  in software developement delivered by the high school of communication SUPCOM, he also holds a bachelor degree in finance delivered by  the  economic sciences and  management  university of Tunis "FSEGT".

He also holds:

MCPD enteprise solutions developement 3.5 certification and MCTS distibuted application developement 2.0

 He's a freelance developer since 2006. Actually woking on the WPF, .Net framewok 3.5, silverlight and the other .Net new features, in addition, he is painter and sculptor.

Looking for C# Consulting?
C# Consulting is founded in 2002 by the founders of C# Corner. Unlike a traditional consulting company, our consultants are well-known experts in .NET and many of them are MVPs, authors, and trainers. We specialize in Microsoft .NET development and utilize Agile Development and Extreme Programming practices to provide fast pace quick turnaround results. Our software development model is a mix of Agile Development, traditional SDLC, and Waterfall models.
Click here to learn more about C# Consulting.
 
Introducing MaxV - one click. infinite control. Hyper-V Hosting from MaximumASP.
Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
Dynamic PDF
ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications.
Discover the top 5 tips for understanding .NET
Ricky Leeks presents the top 5 tips for understanding .NET Interoperability. Learn more.
Nevron Chart for .NET 2010.1 Now Available
The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
ASP.NET 4 Hosting
Get 2 Months Free of ASP.NET Hosting for Only $4.95/month! Receive FREE MS SQL and MySQL Databases Including ASP.NET 4/3.5, MVC 3.0, Silverlight 4, Windows 2008/IIS 7.0 Plus FREE IIS 7 Modules. Host UNLIMITED ASP.NET Web Sites – Click Here!
 
 Post a Feedback, Comment, or Question about this article
Subject:
Comment:
Discover the top 5 tips for understanding .NET Interop
Become a Sponsor
 Comments
Discover the top 5 tips for understanding .NET Interop
 © 2012  contents copyright of their authors. Rest everything copyright Mindcracker. All rights reserved.