2011-03-24 16 views
16

Creé un Procedimiento almacenado que devuelve XML y también me gustaría devolver ese XML en un método que creé.¿Cómo devuelvo XML de un procedimiento almacenado?

Tengo dos problemas. En primer lugar, después de realizar algunas búsquedas, no se recomienda utilizar .ExecuteScalar(); porque trunca cadenas de más de 2033 caracteres.

Por lo tanto, me encontré con una función llamada ExecuteXMlReader(), pero en Visual Web Developer 2010 Express que se ejecuta en .NET 4.0 (C#) es tirar el error "System.Data.SqlClient.SqlCommand' does not contain a definition for 'ExecuteXMlReader' and no extension method 'ExecuteXMlReader' accepting a first argument of type 'System.Data.SqlClient.SqlCommand' could be found"

Aquí está mi procedimiento almacenado:

CREATE PROCEDURE dbo.GETReport 
    (@ReportDate date) 
AS 
SELECT * FROM ReportTbl 
WHERE ReportDate = @ReportDate 
for xml auto, elements 

set nocount on; 

RETURN 

Aquí es mi método:

using System.Data; 
using System.Data.SqlClient; 

... 

     //connect   
     SqlConnection conn = new SqlConnection("Data Source=localhost; User Id=foo; Password=foo; Initial Catalog=Database1"); 
     conn.Open(); 

     //create command 
     SqlCommand cmd = new SqlCommand("dbo.GETReport", conn); 
     cmd.Parameters.AddWithValue("@ReportDate", "3/24/2011"); 
     cmd.CommandType = CommandType.StoredProcedure; 

     DataReader rd = cmd.ExecuteXMlReader(); //this is where error is occuring 
     //also, it is throwing an error for DataReader as well saying there is no 
     //type of namespace with that name 
     rd.Read(); 

     string s = rd.ReadOuterXml(); //also dont know if this is how i should return the XML 

en segundo lugar, además de la cuestión ExecuteXMLReader(), no sé si el retorno de una string es la forma correcta de devolver XML en primer lugar ... ¿Hay otro tipo de objeto en el que debería convertirlo? ¿O otra función que debería usar?

Gracias de antemano!

Respuesta

25

Primero, SqlCommand tiene un método ExecuteXmlReader, no ExecuteXMlReader como escribió (esto es una falta de ortografía). En segundo lugar, el método SqlCommand.ExecuteXmlReader devuelve un valor de tipo XmlReader, no un DataReader como en su ejemplo. Por lo que cambiar su código para:

using (XmlReader reader = cmd.ExecuteXmlReader()) 
{ 
    while(reader.Read()) 
    { 
     string s = reader.ReadOuterXml(); 
     // do something with s 
    } 
} 

debería resolver el problema.

+0

que funcionó muy bien, pero una pregunta rápida ... ¿hay alguna manera de devolver el XML como XML y no como una cadena? – AngeloS

+2

El 'XmlReader' es la forma subyacente de leer cualquier XML. Lo usaría para cargar un XDocument o XmlDocument, usando XDocument.Load (reader), por ejemplo. –

+2

@Angelo, podría usar algo similar a 'XmlDocument document = new XmlDocument(); document.Load (reader); 'o use' XDocument.Load (reader) 'como se menciona en @John. Gracias, @John! – Alex

3

que tenían problemas con la simple approach de @Alex y mejor suerte con this approach:

// Execute a SqlCommand that you've created earlier. 
// (Don't forget your 'using' statements around SqlConnection & SqlCommand!) 
XmlReader xmlReader = cmd.ExecuteXmlReader(); 

// This is where our XML will end up 
var xmlDocument = new XmlDocument(); 

// Now xmlReader has the XML but no root element so we can't 
// load it straight into XmlDocument :(But we can use XPathDocument 
// to add a node for us first. 
var xp = new XPathDocument(xmlReader); 
var xn = xp.CreateNavigator(); 
XmlNode root = xmlDocument.CreateElement("YourFavouriteRootElementName"); 
root.InnerXml = xn.OuterXml; 
xmlDocument.AppendChild(root); 

// Now xmlDocument has all the XML you have dreamed of 

Utilizando el reader.Read() ... var s = reader.ReadOuterXml() alguna manera perdido algunos de los elementos en mi XML más complejo ya. No me molesté en investigar por qué, pero cambiar a XPathDocument funcionó para mí.

Cuestiones relacionadas