Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I return variable column lengths via LINQ to SQL

Tags:

c#

.net

sql

tsql

linq

I've had a search round the internet and cannot find anything that directly matches what I'm after....

I have a stored procedure that returns a fixed set of columns (let's say ColumnA, ColumnB and ColumnC) and then additionally returns an indeterminate number / signature of additional columns (maybe ColumnD, ColumnE and ColumnF, or ColumnF, ColumnP, ColumnT and ColumnW).

The dynamic part of the query is determined by an Id param to the proc.

Unfortunately I am not in control of the schema and it has been poorly designed to have a very large number of unrelated columns added to the end (and they keep adding them), rather than having an additional table(s) to store this effectively.

As a result, I am unable to return a determinate set of columns at compile time, so LINQ to SQL cannot determine the return type of the stored procedure.

Do I have any other options, or ways I can get around this? Here's an example of what I am doing below. Can I re-write this to work with LINQ to SQL? I am writing the application with C# and SQL Server 2008 if that helps.

Thanks.

CREATE PROCEDURE [Foo].[GetBar]
(
    @Id INT,
    @FooVar VARCHAR(50),
    @BarVar DATE
)

AS 
BEGIN

CREATE TABLE #TempTbl 
(     
    [ColumnName] VARCHAR(50)
)

INSERT #TempTbl EXEC [Foo].GetColumnNames @Id
DECLARE @ColumnNameList NVARCHAR(max) 
SET @ColumnNameList = '' 
SELECT @ColumnNameList = COALESCE(@ColumnNameList + '],[', '') + ColumnName FROM #TempTbl
DROP TABLE #TempTbl
SELECT @ColumnNameList = @ColumnNameList + ']'
SELECT @ColumnNameList = SUBSTRING(@ColumnNameList, 3, LEN(@ColumnNameList) )

DECLARE @FixedColumns VARCHAR(200)
DECLARE @SelectQuery NVARCHAR(max) 
DECLARE @WhereQuery VARCHAR (100)
DECLARE @FullQuery NVARCHAR(max) 
DECLARE @ParamaterDef nvarchar (100)
DECLARE @Foo VARCHAR(50)
DECLARE @Bar DATE

SET @FixedColumns = N'[ColumnA], [ColumnB], [ColumnC], '
SET @SelectQuery = N'SELECT ' + @FixedColumns + @ColumnNameList + N' FROM [Foo].[FooBar] '
SET @WhereQuery = N'WHERE [Foo] = @Foo AND [Bar] = @Bar'
SET @FullQuery = @SelectQuery + @WhereQuery   
SET @ParamaterDef = N'@Foo VARCHAR(50), @Bar DATE'

EXECUTE sp_executesql @FullQuery, @ParamaterDef, @Foo = @FooVar, @Bar = @BarVar 

END 
like image 267
Mike Avatar asked May 29 '12 08:05

Mike


1 Answers

Can you not just use a SQL Data Adapter that fills a DataSet? You could then use LINQ to DataSet and perform all of your LINQ operations:

DataTable yourDataTable = ds.Tables["TableName"];

var query =
   from yourDataTable in yourDataTable.AsEnumerable()
   select new
   {
      NewField = yourDataTable.Field<int>("ColumnName"),
      NewField2 = yourDataTable.Field<string>("ColumnName2"),
   };

MSDN (LINQ to DataSet)

MSDN (Single table queries using LINQ to DataSet

like image 200
Darren Avatar answered Sep 29 '22 10:09

Darren