2011-12-16 44 views
5

Lưu ý: Tôi không thể tìm thấy câu hỏi chính xác này trong tìm kiếm. Tôi tìm thấy một câu hỏi tương tự ở đây trên Stack Overflow, dẫn tôi đến giải pháp. Tôi đang đăng câu hỏi và giải pháp để người tiếp theo gặp sự cố có thể dễ dàng tìm ra giải pháp. Tôi đã đặt câu hỏi CommunityWiki nếu vẫn còn có thể - tôi không tìm kiếm đại diện từ điều này.System.InvalidCastException: Không thể chuyển đổi giá trị tham số từ XElement thành một chuỗi


Tôi cố gắng để sử dụng ADO.NET để gọi một thủ tục lưu trữ SQL Server 2005 mà chấp nhận một tham số của Xml loại:

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; 

tôi vượt qua XML như một LINQ to đối tượng XML XElement

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

sau

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 
} 

này không thành công trên dòng ExecuteReader với ngoại lệ:

System.InvalidCastException: Không thể chuyển đổi giá trị tham số từ một XElement vào một String. ---> System.InvalidCastException: Đối tượng phải triển khai IConvertible

Cách chính xác để chuyển số XElement thành thủ tục được lưu trữ là gì?

+1

thể trùng lặp của [C#/SQL - Có gì sai với SqlDbType.Xml trong thủ tục] (http://stackoverflow.com/questions/574928/c-sql-whats-wrong-with-sqldbtype-xml -in-thủ tục) –

+0

Không trùng lặp - đó là một ngoại lệ khác. –

+1

Bạn đang gặp phải vấn đề gì? Bạn đã thử một cái gì đó và nó đã không hoạt động? – JsonStatham

Trả lời

9

Mã SqlClient không cho phép XElement được truyền trực tiếp.

Một điều bạn có thể làm là sử dụng System.Data.SqlTypes.SqlXml class để vượt qua XML:

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

Tùy thuộc vào mã của bạn, bạn có thể cần phải đặt XmlReader trở về từ mã CreateReader thành một khối using.

0

Dưới đây là hai phương pháp mở rộng tôi đã xây dựng dựa trên câu trả lời của 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()) 
     }); 
    } 
} 
Các vấn đề liên quan