I started with LINQ and MVC recently, and found the following restriction in LINQ to SQL:
Thus the LINQ to SQL code generator does not support the following:
Stored procedures that produce results based on temporary table.
While this statement is true for generated code, you can still manually work around the problem.
When you create a LINQ to SQL item, VS creates a .dbml and a .designer.cs file for the database connection specified. The .cs file contains the DataContext, which is declared as a public partial class, which means we can easily extend it.
Suppose we have a database called MyDB and a stored procedure MyProc which collects data in a temporary table and returns this data using a SELECT * FROM #Temp.
To declare the #Temp record in C#, we need to create a separate .cs file (e.g. MyDBExt.cs).
Start with a C# class mapping to the #Temp table (taken from one of my projects):
[Table]
public partial class MyProc_Result
{
public MyProc_Result() { }
[Column]
public int User_OID;
[Column]
public string User_ID;
[Column]
public int ItemCount;
[Column]
public string Description;
}
What’s important here is that the class has the [Table] attribute, and each field has a [Column] attribute from the System.Data.Linq.Mapping namespace. No getters and setters necessary, as in the generated class file.
Next, extend the partial class from the original .designer.cs file and create an additional method for your SP:
[Function(Name = "dbo.MyProc")]
public IEnumerable<MyProc_Result> MyProcResultset(
.. copy parameters from original declaration .. )
{
IExecuteResult result = this.ExecuteMethodCall(this,
((MethodInfo)(MethodInfo.GetCurrentMethod())), ..params..);
return result.ReturnValue as IEnumerable<MyProc_Result>;
}
Since overloaded methods are distinguished by the types of their parameters, and not by their return type, you have to change the method name for your extension. (Optionally, you can derive your own class and override the original method)
April 6, 2009 at 20:33 |
This was very helpful. Thank you.
June 26, 2009 at 7:23 |
Instead Of create Temporary Table, Create Variable Table.
ex:
create table #table_name(…..)
change the above Table like the Following
Declare @table_name table(…..).
It will work.
June 30, 2009 at 17:10 |
We are returning 2 temp tables from stored procedures.
We have created 2 class in dbml file which have same schema as temporary tables.
We have associcated these tables. The problem is data is getting loaded in first class collection but while loading data in second class collection it gives error as Invalid Object Name “Class name”.
Can you help on this
August 2, 2009 at 16:36 |
Worked using a table variable as suggested by Er Suresh Ganesan. Thanks.
August 16, 2009 at 20:02 |
Using table variable for return table from stored procedure is works fine. Thanks for this idea
October 20, 2009 at 23:17 |
Very helpfull thanks!
Just a caveat, using table type instead of temporary inmemory table is only applicable in sql server >=2005 in sql server 2000 we still have to use the temp table method.
Greeting,
Teixeira
October 21, 2009 at 12:24 |
Hi all!
Just want to give my input again, because i found that i couldn’t accomplish the goal just using the class with public members inside without gets and sets, didn’t work for me….when trying to bind it directly to the gridview control.
So, I had to use gets and sets to get it done!
JIC someone steps in the same, here’s another experience report that might help.
Greetings,
Teixeira
October 22, 2009 at 10:27 |
Accessors are a good point.
I did not use my classes in GridViews and other controls yet, so the problem didn’t occur for me.
November 14, 2009 at 18:16 |
I found an easy workaround for this problem. If you create a stored proc say : SELECT * FROM Products then drag it into the .dbml designer as usual.
You can then go back to the sproc and modify it any way you want including adding temp tables and using ‘exec’ which I also found would cause problems. As long as your final select columns match the object, then your OK.