2011-12-16 5 views
5

Nota: Non è stato possibile trovare questa domanda esatta in una ricerca. Ho trovato una domanda piuttosto simile qui su Stack Overflow, che mi ha portato alla soluzione. Sto postando la domanda e la soluzione in modo che la prossima persona con il problema possa trovare più facilmente la soluzione. Avrei fatto la domanda CommunityWiki se fosse ancora possibile - Non sto cercando un rappresentante da questo.System.InvalidCastException: Impossibile convertire il valore del parametro da XElement a una stringa


Sto cercando di utilizzare ADO.NET per chiamare una stored procedure di SQL Server 2005, che accetta un parametro di tipo 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; 

passo il XML come LINQ to XML oggetto XElement

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

tardi

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 
} 

Questo non sulla linea ExecuteReader ad eccezione:

System.InvalidCastException: Impossibile convertire il valore di parametro da un XElement in una stringa. ---> System.InvalidCastException: oggetto deve implementare IConvertible

Qual è il modo corretto per passare un XElement a una stored procedure?

+1

possibile duplicato del [C#/SQL -? Cosa c'è di sbagliato con SqlDbType.Xml nelle procedure] (http://stackoverflow.com/questions/574928/c-sql-whats-wrong-with-sqldbtype-xml -in-procedure) –

+0

Non è un duplicato - è un'eccezione diversa. –

+1

Che problema stai avendo? Hai provato qualcosa e non ha funzionato? – JsonStatham

risposta

9

Il codice SqlClient non consente il passaggio diretto di XElement.

Una cosa che si può fare è quella di utilizzare il System.Data.SqlTypes.SqlXml class per passare il XML:

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

A seconda del codice, potrebbe essere necessario inserire il XmlReader restituito dal codice CreateReader in un blocco using.

0

Ecco due metodi di estensione che ho creato sulla base della risposta di 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()) 
     }); 
    } 
} 
Problemi correlati