2017-10-12 1 views
1

J'ai lu beaucoup de messages et pense que je comprends les concepts, mais mon petit tableau d'ints échoue à passer d'un module C#/EF à un proc stocké SQL Server . En espérant que d'autres yeux peuvent repérer le problème.Passage d'ints à T-SQL stocké par proc framework d'entité

J'utilise EF6, Framework .Net 4.5, SQL Server 2014

Dans la base de données que j'ai créé ces types/procs:

CREATE TYPE [dbo].[IntsTTV] AS TABLE(
    [Id] [int] NOT NULL 
) 

Notez que une table nommée 'personne' existe avec les colonnes 'Id' (int) et 'LastName' (nvarchar), et a des données.

CREATE PROCEDURE [dbo].[GetUsers] 
@UserIds dbo.IntsTTV READONLY 
AS 
BEGIN 
    SELECT p.LastName 
    FROM [dbo].[Person] p 
    INNER JOIN @UserIds ids On p.Id = ids.Id; 
END 

// code C#

SqlMetaData[] columns = new SqlMetaData[1]; 
columns[0] = new SqlMetaData("Id", SqlDbType.Int); 

SqlDataRecord row = new SqlDataRecord(columns); 
row.SetInt32(0, 1); // Id of '1' is valid for the Person table 

SqlDataRecord[] table = new SqlDataRecord[1]; 
table[0] = row; 

SqlParameter parameter = new SqlParameter(); 
parameter.SqlDbType = SqlDbType.Structured; 
parameter.ParameterName = "@UserIds"; 
parameter.TypeName = "dbo.IntsTTV"; 
parameter.Direction = ParameterDirection.Input; 
parameter.Value = table; 

SqlParameter[] parameters = new SqlParameter[1]; 
parameters[0] = parameter; 


var res = _db.Database.SqlQuery<string>("GetUsers", parameters).ToList(); 

Le code n'appelle avec succès le proc, et si je coder en dur le proc de revenir simplement une sélection de LastName de puis le code C# ne reçoit que . Cela me dit ce que est de travail.

Si j'appelle le proc à partir d'un autre code T-SQL, en passant un paramètre table (IntsTTV) de ints, cela fonctionne. Dans le proc, si je sélectionne le nombre de lignes du tableau de paramètres passé, je reçois zéro lors de l'appel du code C#, mais je reçois un compte correct lors de l'appel à partir du code T-SQL.

Qu'est-ce qui me manque, s'il vous plaît?

Répondre

1

Voici comment j'appelle une procédure stockée avec un paramètre table évalué. La principale différence étant que j'utilise un paramètre DataTable. Je me souviens avoir eu des problèmes avec les liaisons de noms de paramètres, mais je ne me souviens pas exactement de ce qu'ils étaient. Ceci explique la modification que j'ai faite dans la syntaxe de l'appel de procédure. Je sais que celui-ci devrait fonctionner.

var dataTable = new DataTable(); 
dataTable.TableName = "dbo.IntsTTV"; 
dataTable.Columns.Add("Id", typeof(int)); 
dataTable.Rows.Add(1); // Id of '1' is valid for the Person table 

SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured); 
parameter.TypeName = dataTable.TableName; 
parameter.Value = dataTable; 

var res = _db.Database.SqlQuery<string>("EXEC GetUsers @UserIds", parameter).ToList(); 
1

Cela a fonctionné! Pour le plaisir des autres, je vais poster le code précis ici, que j'ai dû modifier légèrement.

var dataTable = new DataTable(); 
dataTable.TableName = "dbo.IntsTTV"; 
dataTable.Columns.Add("Id", typeof(int)); 
dataTable.Rows.Add(1); // Id of '1' is valid for the Person table 

SqlParameter parameter = new SqlParameter("UserIds", SqlDbType.Structured); 
parameter.TypeName = "dbo.IntsTTV"; 
parameter.Value = dataTable; 
var res = _db.Database.SqlQuery<string>("EXEC dbo.GetUsers @UserIds", parameter).ToList(); 
+0

bien! vous devriez maintenant accepter une réponse – jbl

0

Je sais que cela a été répondu par trouvé une autre façon qui pourrait aider quelqu'un d'autre là-bas

STRING_SPLIT

declare @intArray nvarchar(1000) 
set @intArray = '1,2,3,4,5' 
select value from STRING_SPLIT(@intArray , ',') 

Cela renverra une nouvelle table avec les numéros dans votre @intArray

Ensuite, vous avez juste besoin de l'utiliser comme une table normale

select * from myMainTable where Id in (select value from STRING_SPLIT(@intArray , ','))