2011-03-24 125 views
16

我创建了一个返回XML的存储过程,我也希望在创建的方法中返回该XML。如何从存储过程返回XML?

我有两个问题。首先,在进行一些搜索之后,建议不要使用.ExecuteScalar();,因为它会截断2033个字符以上的字符串。

于是,我找到了一个叫ExecuteXMlReader()功能,但在Visual Web Developer 2010和学习表达对.NET 4.0(C#)运行时,它抛出错误"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"

这里是我的存储过程:

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

set nocount on; 

RETURN 

这里是我的方法:

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 

其次,除了ExecuteXMLReader()问题,我不知道是否返回字符串是首先返回XML的正确方法...是否有另一个对象类型我应该将其转换为?或者我应该使用另一个函数?

预先感谢您!

回答

25

首先,SqlCommand有一个ExecuteXmlReader方法,而不是你写的ExecuteXMlReader(这是拼写错误)。其次,SqlCommand.ExecuteXmlReader方法返回的值类型为XmlReader,而不是DataReader,如同您的示例中所示。因此将您的代码更改为:

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

应解决问题。

+0

工作很好,但问题很快..有没有办法将XML作为XML返回而不是字符串? – AngeloS 2011-03-24 19:35:13

+2

'XmlReader'是读取任何XML的底层方法。例如,您将使用它来加载XDocument或XmlDocument,使用XDocument.Load(reader)。 – 2011-03-24 19:38:12

+2

@Angelo,你可以使用类似于'XmlDocument document = new XmlDocument(); document.Load(reader);'或者像@John所说的那样使用'XDocument.Load(reader)'。谢谢,@约翰! – Alex 2011-03-24 19:42:18

3

我曾与simple approach从@Alex和更好的运气麻烦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 

使用reader.Read() ... var s = reader.ReadOuterXml()种种原因错过了,我再更复杂的XML元素。我没有打扰调查为什么,但切换到XPathDocument为我工作。