Reputation: 4918
I have set up a stored procedure which I am passing a data table into and calling directly from Entity Framework.
I have created a Type with the following sql:
CREATE TYPE Regions AS TABLE
( RegionId int,
Region varchar(max),
BodyId int NULL,
Body varchar(max),
AreaId int NULL,
Area varchar(max),
Location varchar(max),
LocationId int
)
My test stored procedure is as follows:
CREATE PROCEDURE [dbo].[GetStats]
@regions dbo.Regions READONLY
AS
BEGIN
SELECT * INTO #tmptble from @regions
Select * from #tmptble
END
I am using the following to call the stored procedure:
SqlParameter param = new SqlParameter();
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.Regions";
param.Value = myDataTable;
param.ParameterName = "@regions";
return _context.Database.SqlQuery<RegionDetails>("GetStats", param);
My datatable is definitely the correct format as I have run this through profiler passing it in to the stored procedure and you can see all the inserts appearing. If I generate a test table from all the insert statements the procedure runs fine against that but when I run it with the passed in datatable it just returns no rows.
EDIT - for further info When I run this through profiler I get the following:
declare @p3 dbo.Regions
~~~a Load of insert statements of all my datatable data~~~
exec sp_executesql N'GetStats',N'@regions [dbo].[Regions] READONLY',@regions =@p3
UPDATE on the above I have been playing around with what is shown in profiler and if I replace
exec sp_executesql N'GetStats',N'@regions [dbo].[Regions] READONLY',@regions =@p3
with
EXEC GetStats @p3
Again it works. Has anyone got any clue why?
Upvotes: 0
Views: 658
Reputation: 4918
Answer based on @SteveD's answer but to clarify exactly what I did incase it helps any one else. There was nothing wrong with my stored procedure. It was purely my calling of it. It needed the parameter name in the actual call like so:
SqlParameter param = new SqlParameter();
param.SqlDbType = SqlDbType.Structured;
param.TypeName = "dbo.Regions";
param.Value = myDataTable;
param.ParameterName = "@regions";
return _context.Database.SqlQuery<RegionDetails>("GetStats @regions", param);
Upvotes: 0
Reputation: 867
Try this approach:
//create parameter
var param = new SqlParameter("@regions", SqlDbType.Structured);
param.Value = myDataTable;
param.TypeName = "dbo.Regions";
//return result set
return _context.ExecuteFunction<RegionDetails>("dbo.Regions", param);
//OR
//execute stored procedure for inserts, returns rows effective
return _context.Database.ExecuteSqlCommand("exec dbo.Regions @regions", param);
Upvotes: 1