简体   繁体   中英

How can I pass an XML string as a parameter of a query via dapper?

I need to pass a list of thousands of IDs to a query as a parameter to filter on, using Dapper.

Even if there wasn't a limit WRT the amount of parameters you can send to SQL Server, looping through the collection and creating numerous parameters is an inelegant solution.

Luckily I've seen that you can send an XML string which the query than can unpack using XTbl.value and .nodes() .

But I cannot figure out how to pass this XML string via Dapper.

In the end it wasn't that hard, it just took some effort combining various nuggets of knowledge and a bit of trial and error.

This is a simplified version of the query:

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]

It is embedded as an .sql file in my solution, and I read it using my QueryRetriever class -- check https://codereview.stackexchange.com/q/214250/10582 for its code.

The IDs to pass to the query need to be converted to an XML string:

        var idfsAsXml = new XDocument(
                new XElement("root",
                    excelRecords
                        .Select(x => x.Idf)
                        .Distinct()
                        .Select(x => new XElement("Idf", x))))
            .ToString();

I then use Dapper's DynamicParameters to create a parameter:

        var dynamicParameters = new DynamicParameters();
        dynamicParameters.Add("@Idfs", idfsAsXml, DbType.Xml, ParameterDirection.Input);

And then I pass that parameter as DbType.Xml (with ParameterDirection.Input ):

        using (var connection = new SqlConnection(_connectionString))
        {
            regularRecords = connection.Query<RegularRecord>(
                    QueryRetriever.GetQuery("GetRegularRecords.sql"),
                    dynamicParameters
                )
                .ToList();
        }

Perhaps this will be of help to others.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM