系统.InvalidCastException:将参数值从XElement转换为字符串失败



注意:我无法在搜索中找到这个确切的问题。我在Stack Overflow上发现了一个类似的问题,这让我找到了解决方案。我张贴问题和解决方案,以便下一个有问题的人可以更容易地找到解决方案。如果可能的话,我早就把这个问题写在CommunityWiki上了——我不是在找这个代表。


我正在尝试使用ADO。. NET调用接受Xml类型参数的SQL Server 2005存储过程:

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;

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

var idList = new XElement(
    "Persons",
    from i in selectedPeople
    select new XElement("id", i));
后来

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
}

这在ExecuteReader行失败,有以下例外:

系统。InvalidCastException:将参数值从XElement转换为字符串失败。——>系统。InvalidCastException: Object必须实现IConvertible

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

SqlClient代码不允许直接传递XElement

您可以做的一件事是使用System.Data.SqlTypes.SqlXml类传递XML:
cmd.Parameters.Add(
    new SqlParameter
    {
        ParameterName = "@ListOfIds",
        SqlDbType = SqlDbType.Xml,
        Value = new SqlXml(idList.CreateReader())
    });

根据您的代码,您可能需要将CreateReader代码返回的XmlReader放置到using块中。

下面是我根据John Saunders的回答构建的两个扩展方法。

public static class ExtensionMethods
{
    public static void AddXml(this SqlParameterCollection theParameters, string name, XElement value)
    {
        theParameters.Add(new SqlParameter()
        {
            ParameterName = name,
            SqlDbType = SqlDbType.Xml,
            Value = new SqlXml(value.CreateReader())
        });
    }
    public static void AddXml(this SqlParameterCollection theParameters, string name, string value)
    {
        theParameters.Add(new SqlParameter()
        {
            ParameterName = name,
            SqlDbType = SqlDbType.Xml,
            Value = new SqlXml(XElement.Parse(value).CreateReader())
        });
    }
}

相关内容

  • 没有找到相关文章

最新更新