System.InvalidCastException:无法将参数值从XElement转换为String

Joh*_*ers 5 c# sql-server ado.net sql-server-2005 sqlclient

注意:我无法在搜索中找到这个确切的问题.我在Stack Overflow上找到了一个类似的问题,这让我得到了解决方案.我发布了问题和解决方案,以便下一个有问题的人可以更轻松地找到解决方案.如果仍然可以,我会提出社区维基的问题 - 我不是在寻找代表.


我试图使用ADO.NET来调用SQL Server 2005存储过程,该过程接受Xml类型的参数:

CREATE PROCEDURE dbo.SomeProcedure(
    @ListOfIds Xml)
AS
BEGIN
    DECLARE
            @Ids TABLE(ID Int);
    INSERT INTO @Ids
    SELECT ParamValues.ID.value('.', 'Int')
    FROM @ListOfIds.nodes('/Persons/id') AS ParamValues(ID);

    SELECT p.Id,
           p.FirstName,
           p.LastName
    FROM Persons AS p
         INNER JOIN @Ids AS i ON p.Id = i.ID;
END;
Run Code Online (Sandbox Code Playgroud)

我将XML作为LINQ传递给XML XElement对象

var idList = new XElement(
    "Persons",
    from i in selectedPeople
    select new XElement("id", i));
Run Code Online (Sandbox Code Playgroud)

后来

SqlCommand cmd = new SqlCommand
                 {
                     Connection = conn,
                     CommandText = "dbo.SomeProcedure",
                     CommandType = CommandType.StoredProcedure
                 };
cmd.Parameters.Add(
    new SqlParameter
    {
        ParameterName = "@ListOfIds",
        SqlDbType = SqlDbType.Xml,
        Value = idList)
    });
using (var reader = cmd.ExecuteReader())
{
    // process each row
}
Run Code Online (Sandbox Code Playgroud)

ExecuteReader在例外的情况下失败:

System.InvalidCastException:无法将参数值从XElement转换为String.---> System.InvalidCastException:对象必须实现IConvertible

传递XElement给存储过程的正确方法是什么?

Joh*_*ers 9

SqlClient代码不允许直接传递XElement.

您可以做的一件事是使用System.Data.SqlTypes.SqlXml来传递XML:

cmd.Parameters.Add(
    new SqlParameter
    {
        ParameterName = "@ListOfIds",
        SqlDbType = SqlDbType.Xml,
        Value = new SqlXml(idList.CreateReader())
    });
Run Code Online (Sandbox Code Playgroud)

根据您的代码,您可能需要XmlReaderCreateReader代码中返回的代码放入using块中.