ExecutestoreQuery avec les paramètres TVP
-
12-11-2019 - |
Question
J'ai une procédure stockée dans ma base de données qui prend un paramètre de valeur de table, une liste d'objets IDTable qui contiennent une seule colonne d'ID entier.
J'ai un modèle d'entité pour la base de données et je veux faire ce qui suit ...
ProjectEntities projectEntities = new ProjectEntities ();
DataTable stationIds = new DataTable();
stationIds.Columns.Add("Id");
stationIds.Rows.Add(1);
stationIds.Rows.Add(2);
SqlParameter parameter = new SqlParameter("@stationIds",stationIds);
parameter.TypeName = "IdTable";
var parameters = new object[] {parameter};
var results = projectEntities .ExecuteStoreQuery<ProjectSummary>("exec ProjectSummary", parameters);
var count = results.Count();
Cela s'exécute et ne renvoie aucun résultat, alors qu'il devrait retourner un tas d'entités de projets en état.
Quand je le profile dans SQL Profiler, j'obtiens ce qui suit
declare @p3 IdTable
insert into @p3 values(N'1')
insert into @p3 values(N'2')
exec sp_executesql N'exec ProjectSummary',N'@stationIds [IdTable] READONLY',@stationIds=@p3
Si je déclare que la procédure stockée est
ALTER PROCEDURE [dbo].[ProjectSummary]
@stationIds [dbo].[IdTable] READONLY
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT * FROM @stationIds
...
Ensuite, je ne reçois pas de résultats, il semble que le paramètre TVP passe vide.
Où comme si j'exécute manuellement
declare @p3 IdTable
insert into @p3 values(N'1')
insert into @p3 values(N'2')
EXEC [ProjectSummary]
@stationIds = @p3
GO
J'obtiens les valeurs 1 et 2 renvoyées à partir de la requête sélectionnée.
Donc, il semble que je souhaite utiliser Exec plutôt que SP_EXECUTESQL lorsque j'exécute ExecuteToreCommand. Compte tenu de l'exemple de code ci-dessus, comment diable dois-je faire cela?
La solution
Il s'avère que l'appel ExecuteToreQuery était incorrect, il devrait être
SqlParameter stations = new SqlParameter { ParameterName = "p0", Value = ids, TypeName = "[dbo].[IdTable]", SqlDbType = SqlDbType.Structured };
var parameters = new object[] { stations };
var results = projectEntities.ExecuteStoreQuery<ProjectSummary>("exec ProjectSummary @p0", parameters);
J'avais donc besoin de nommer le paramètre et d'ajouter le @ p0 à la commande exec.