views:

209

answers:

2

Where I work it is a requirement for us to go through stored procedures as a mechanism to access our data through code. I am using LINQ2SQL to minimize this pain so that I can work with objects instead of ADO.NET directly. I have a situation Linq2SQL is consuming one of my stored procedures an generating code where the return type from the stored proc call is an int. The stored procedure actually returns a dataset. After doing a little research I have found that this is because the SQLClient library can not properly parse the sproc to generate the expected metadata that Linq2SQL uses to create the object graph. My question is how can sprocs (even complex ones) be structured so that you get an object graph out of linq2sql, or in other words what should you avoid having in your stored procedure that will create confusion for the SQLClient library to not understand how to generate the metadata that linq2sql consumes in order to create an object graph?

+4  A: 

This is not actually a limitation of LINQ to SQL but rather of SQL Server which can not always tell a client what the return type would be without actually running it when it contains temporary tables, cursors or dynamic SQL.

As running it with invalid parameters could be potentially catastrophic it doesn't try.

You can either set it by hand using the designer or if it is absolutely okay to run the stored procedure with invalid data (i.e. it is purely passive) then you can add SET FMTOPT OFF to the start of the stored procedure.

DamienG
After looking at the sproc we are doing a few selects into variables at the top of the sproc to set things up but we also have an Exec sprc command that returns an out param in th body of the sproc as well. I would guess that the selects into variables should not be a problem for Linq2Sql but it could be the Exec command which may be throwing it off. Do you know if this would cause a problem for Linq2Sql? Another point of interest is the Exec sproc has an out param, which is being used in the body of the main sproc.Best Regards,Michael
Michael Mann
Avoiding the Exec sproc would be a good start - it can easily lead to SQL injection and hurts performance just as much as dynamic SQL.Without seeing the SP itself it is difficult to guess how it could be rewritten.
DamienG
+1  A: 

DamienG works on the LinqToSql team at Microsoft and I have upvoted his answer as correct.

That said, he likely won't advise you away from LinqToSql and I think it's very important to consider that option.

Trying to guess the return type of a stored procedure is very difficult and LinqToSql does it as well as anyone (for SQL Server). That said, there are very compelling reasons not to use stored procedures:

Stored procedures are bad, m'kay?

If you must protect your tables from developers for "security reasons" (which I'm guessing is the situation you are in), it's best to do that with views instead of stored procedures.

If you are using views, you then have a lot better options in the ORM department than LinqToSql.

The main problem you are going to run into with LinqToSql in this regard is that what works fine for 5 stored procedures in a tiny database doesn't work fine for 50 or 500 stored procedures. You can use the O/R Designer to "override" the return type of a stored procedure, but you will have significant syncing issues when stored procedures or the tables, etc. they operate on change. Changes to stored procedures will not get reflected in the O/R Designer unless you remove the stored procedure from the O/R Designer, re-add it, and then reapply your custom override. If your project is like any normal project, the tables and stored procedures change often and this sync issue soon becomes a nightmare because it's completely manual and if you fail to do it correctly you will get very strange errors at runtime.

I would strongly advise against continuing down the path you are on.

Michael Maddox
I know who Damien is an I value his comments. The reason for using stored procedures as a mechanism to access our data is not something I personally have any control over. It is an architectural decision and as a result that is what we are consuming as .NET developers. My goal in asking this question is that we have decided to use LINQ2SQL as our O/R mapping tool of choice, and I would like to provide our DBA group with whatever information I can so that they can write the stored procedures in such a way as I can consume it using LINQ2SQL instead of having to use ADO.NET.
Michael Mann