Entity Framework v4 - Simple Stored Procedure Select Statement from Linked Server (Open Query) Returning -1
-
03-07-2021 - |
문제
In SQL Server, I have created a stored procedure which fires a simple select statement (with SET NOCOUNT OFF) using Open Query to query data from a linked server. When querying this data in SQL Server, the correct results are brought back, e.g:
SELECT * FROM OPENQUERY(SERVER, ''SELECT * FROM db.table WHERE field = ' + '''' + '''' + @var+ '''' + ''''')'
I now have a C# WinForms application that uses Entity Framework v4 to access the data, and want to access this stored procedure in code.
I did the usual 'Update Model from Database' and added the stored procedure, then chose to add a function import (called getData for example). I then noticed after clicking 'Get Column Information', I received the following message:
'The selected stored procedure returns no columns'
At this point I clicked OK and then wrote some simple code to access the SP (as follows):
using(var context = new MyContext())
{
var result = context.getData('paramdata');
}
When stepping through the code, result is set to '-1'. After doing some reading someone suggested to set NOCOUNT to OFF in the stored procedure which I did but made no difference.
I am not sure why this works from a query in SQL Server but not Entity Framework?
Is there a way I can get this to work?
Thanks in advance.
해결책
Because you're using OpenQuery the column list is not known to the SQL server.
Try creating a table variable, inserting the results of your openquery into that, and selecting from the table variable.
declare @t table(ID int, value nvarchar(50))
insert @t (ID, value)
select Id,Value FROM OPENQUERY(SERVER, 'SELECT * FROM db.table')
select ID, Value from @t
다른 팁
Your query does not return any data, so no row information is returned. Try to fix your query and check on what database you are running. And fix you select *, which is a real bad pattern for quering databases.
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @Query nvarchar(max);
DECLARE @LinkServer varchar(20);
DECLARE @CatalogSch varchar(20);
DECLARE @DIVISION_NO INT;
DECLARE @BLOCK_NO INT;
DECLARE @LOT_NO INT
/* With this code I get the server and catalog (production or develpment environment)*/
EXEC [dbo].[usp_GetLinkServerAndSchema] 'ACTJO', @LinkServer out, @CatalogSch out;
/* Declare the table */
declare @t table(Division_no int, block_no int, lot_no int)
/* Build the query to get the three values */
SET @Query = 'SELECT @DIVISION_NO = [DIVISION_NO], @BLOCK_NO = [BLOCK_NO], @LOT_NO = [LOT_NO] FROM OPENQUERY ('+@LinkServer+',''
SELECT DIVISION_NO, BLOCK_NO, LOT_NO
FROM '+@CatalogSch+'.[CSS_PREMISE]
WHERE ACCOUNT_NO = '+convert(varchar,@account)+''')'
/* execute the query */
EXEC sp_executesql @Query, N'@DIVISION_NO INT output, @BLOCK_NO INT output, @LOT_NO INT output', @DIVISION_NO output, @BLOCK_NO output, @LOT_NO output;
/* insert the values into the table */
insert @t (Division_no,block_no,lot_no)
select @DIVISION_NO, @BLOCK_NO, @LOT_NO;
/* query the temporary table */
select Division_no,block_no,lot_no from @t