2011-12-16 25 views
5

注:この正確な質問は検索では見つかりませんでした。 Stack Overflowでこれとやや似たような質問があることがわかりました。私は問題と次の人が解決策をより簡単に見つけることができるように質問とソリューションを投稿しています。それがまだ可能だったのであれば、私はCommunityWikiに質問をしたでしょう - 私はこれから担当者を探していません。System.InvalidCastException:パラメータ値をXElementからStringに変換できません


私はXml型のパラメータを受け入れるSQL Server 2005のストアドプロシージャを呼び出すためにADO.NETを使用しようとしています:

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; 

私はLINQ XMLのXElementにオブジェクトとしてXMLを渡します

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行に失敗します。

System.InvalidCastExceptionのは:文字列へのXElementからパラメータ値を変換に失敗しました。 ---> System.InvalidCastException:オブジェクトはIConvertibleを実装する必要があります

XElementをストアドプロシージャに渡す正しい方法は何ですか?

+1

の可能重複[C#の/ SQLに - の手順でSqlDbType.Xmlと何が問題なのですか?](http://stackoverflow.com/questions/574928/c-sql-whats-wrong-with-sqldbtype-xml -in-procedures) –

+0

重複ではなく、別の例外です。 –

+1

あなたはどんな問題を抱えていますか?あなたは何かを試してもうまくいかなかったのですか? – JsonStatham

答えて

9

SqlClientコードでは、XElementを直接渡すことはできません。あなたが行うことができます

ことの一つは、XMLを渡すためにSystem.Data.SqlTypes.SqlXml classを使用することです:

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

あなたのコードに応じて、XmlReaderusingブロックにCreateReaderコードから戻って配置する必要があるかもしれません。

0

ここでは、John Saundersの答えに基づいて作成した2つの拡張方法を示します。

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()) 
     }); 
    } 
} 
関連する問題