J'ai besoin de passer une liste de milliers d'ID à une requête en tant que paramètre à filtrer, à l'aide de Dapper.
Même s'il n'y avait pas de limite WRT sur la quantité de paramètres que vous pouvez envoyer à SQL Server, parcourir la collection et créer de nombreux paramètres est une solution inélégante.
Heureusement, j'ai vu que vous pouvez envoyer une chaîne XML que la requête peut décompresser en utilisant XTbl.value et .nodes () .
Mais je ne peux pas comprendre comment passer cette chaîne XML via Dapper.
En fin de compte, ce n'était pas si difficile, cela a juste pris un certain effort en combinant diverses pépites de connaissances et un peu d'essais et d'erreurs.
Il s'agit d'une version simplifiée de la requête:
SELECT DISTINCT [regular_Person].[Idf] AS [Idf]
, [regular_Person].[FirstName]
, [regular_Person].[LastName]
FROM [regular].[Person] [regular_Person]
WHERE [regular_Person].[Idf] IN (
SELECT Idf
FROM (
SELECT Idf = XTbl.value('.', 'NVARCHAR(10)')
FROM @Idfs.nodes('/root/Idf') AS XD(XTbl)
) AS XmlToData
)
ORDER BY
[regular_Person].[LastName]
, [regular_Person].[FirstName]
Il est incorporé en tant que fichier .sql dans ma solution, et je l'ai lu en utilisant ma classe QueryRetriever
- consultez https://codereview.stackexchange.com/q/214250/10582 pour son code.
Les ID à transmettre à la requête doivent être convertis en une chaîne XML:
var idfsAsXml = new XDocument(
new XElement("root",
excelRecords
.Select(x => x.Idf)
.Distinct()
.Select(x => new XElement("Idf", x))))
.ToString();
J'utilise ensuite DynamicParameters
de Dapper pour créer un paramètre:
var dynamicParameters = new DynamicParameters();
dynamicParameters.Add("@Idfs", idfsAsXml, DbType.Xml, ParameterDirection.Input);
Et puis je passe ce paramètre sous DbType.Xml
(avec ParameterDirection.Input
):
using (var connection = new SqlConnection(_connectionString))
{
regularRecords = connection.Query<RegularRecord>(
QueryRetriever.GetQuery("GetRegularRecords.sql"),
dynamicParameters
)
.ToList();
}
Ce sera peut-être utile aux autres.