Using Stored Procedures In Linq

Using Linq to SQL, you can use stored procedure to return your entities. If you want to use the designer, you can go to the server explorer and drag a stored procedure on an existing entity. This would cause the Linq to SQL designer to generate code for calling a stored procedure that returns your entities. If the stored procedure does not return any particular entity, dragging the stored procedure on the designer would generate a class on the fly which would contain properties that match the columns your stored procedure is returning. If you are using SqlMetal utility to generate your entities, than add /sprocs option to indicate that you want code generated to call stored procs in your database. To better understand what code designer generates, let's take a look at the code generated when calling a simple stored procedure.

image

Dragging the stored procedure generates the following code by Linq to SQL designer.

image

In the above code, the method GetCustsByCity is attributed with Function parameter indicating that this method calls a stored procedure. One of the parameters for function is a name that determines what stored procedure to call. The name parameter matches our stored procedure name. There is additional parameter called IsComposable. If IsComposable is marked as false which in this case it is, means we are calling a stored procedure instead of a function. Our method takes in a parameter of city which we pass to the stored procedure. To call the stored procedure we make use of protected method called ExecuteMethodCall. ExecuteMethodCall takes the class that is calling the method as the first parameter. To conform to this requirement we pass instance of our self in the first parameter. In the second parameter, we are passing methodInfo object by calling GetCurrentMethod using reflection. The reason ExecuteMethodCall needs this info is because MethodInfo object has the metadata that contains our attribute which tells which stored procedure to call. The third parameter is an array of parameters the stored procedure requires to run.

Calling ExecuteMethodCall returns an instance of IExecuteResult. IExecuteResult is an interface interface that has one method and one readonly property.

image

If the stored procedure returns output parameters, you can use GetParameterValue to get the value for the stored procedure. The returnvalue property is responsible for returning tabular results from the stored procedure.

If the stored procedure returns a single result, ReturnValue needs to be casted to ISingleResult of the entity type returned as shown above in our generated code. Since ISingleResult of T implements IEnumerable of T, we can enumerate the result and even further filter our results. Since ISingleResult implements IEnumerable of T, any filters applied are executed in memory and are not converted to SQL and send to the database.

Below is an example of using our GetCustsByCity stored procedure in a Linq query. Notice that after calling our stored procedure in a Linq query we are further filtering the result by getting only customers with contact title of Sales Representative.

image

4 Comments

  • Very nice. Though, the example usage at the end is probably just that (an example), I suspect that if you are taking a stored procedure approach, then you are likely to have a similar stored proc that includes a filter by ContactTitle as well.

    Not to optimize prematurely, I wonder what the performance implications are. It would be interesting to see a comparison between Linq to Stored Procs v. Linq to SQL.

  • I personally prefer linq to sql to stored procs for the same reason you mentioned. Now i have to write another stored proc for a filter by contacttitle which really makes stuff hard to maintain. If i were to be doing this in linq, it would simply be a a matter of adding a linq filter.

  • How to pass optional parameters through linq query.
    For ex -
    var PublicQuery = from m in mobj.usp_SALEINFO_get(Optional1 Param1, param2, optional param3 )
    where
    m.OFFERSTAGE >= 40

    where param1 is optional and param2 is not.

  • Hi,

    Really nice article.


Comments have been disabled for this content.