8

私は、WCF サービス用の一種の「ストア アンド フォワード」アプリケーションに取り組んでいます。メッセージを生の XML BLOB、XElement としてデータベースに保存したいと考えています。データベース呼び出しに必要な XElement タイプに datacontract を変換するのに少し問題があります。何か案は?

4

5 に答える 5

12

これは文字列として返され、db の xml 列に入れることができます。これは、データ契約をシリアライズするために使用できる優れた一般的な方法です。

public static string Serialize<T>(T obj)
{
    StringBuilder sb = new StringBuilder();
    DataContractSerializer ser = new DataContractSerializer(typeof(T));
    ser.WriteObject(XmlWriter.Create(sb), obj);
    return sb.ToString();
}

ところで、linq to sql を使用していますか? 私が尋ねる理由は、あなたの質問の XElement 部分のためです。その場合は、.dbml デザイナでこれを変更して、デフォルトの XElement ではなく文字列を CLR タイプとして使用できます。

于 2009-07-03T04:37:51.267 に答える
9

最も投票された回答 (Jason W. が投稿) は、私にとってはうまくいきませんでした。その答えが最も多くの票を獲得した理由がわかりません。でもいろいろ探したらこんなの見つけた

http://billrob.com/archive/2010/02/09/datacontractserializer-converting-objects-to-xml-string.aspx

これは私のプロジェクトでうまくいきました。いくつかのクラスがあり、クラスとプロパティに datacontract 属性と datamemeber 属性を配置してから、データベースに書き込むことができる XML 文字列を取得したいと考えました。

404 になった場合の上記のリンクのコード:

シリアライズ:

var serializer = new DataContractSerializer(tempData.GetType());
using (var backing = new System.IO.StringWriter())
using (var writer = new System.Xml.XmlTextWriter(backing))
{
    serializer.WriteObject(writer, tempData);
    data.XmlData = backing.ToString();
}

逆シリアル化:

var serializer = new DataContractSerializer(typeof(T));
using (var backing = new System.IO.StringReader(data.XmlData))
using (var reader = new System.Xml.XmlTextReader(backing))
{
    return serializer.ReadObject(reader) as T;
}
于 2010-12-01T18:48:07.760 に答える
2

データベースがSQLServer2005以降の場合は、次のXMLデータ型を使用できます。

private readonly DataContractToSerialize _testContract =
    new DataContractToSerialize
        {
            ID = 1,
            Name = "One",
            Children =
                {
                    new ChildClassToSerialize {ChildMember = "ChildOne"},
                    new ChildClassToSerialize {ChildMember = "ChildTwo"}
                }
        };

public void SerializeDataContract()
{
    using (var outputStream = new MemoryStream())
    {
        using (var writer = XmlWriter.Create(outputStream))
        {
            var serializer =
                new DataContractSerializer(_testContract.GetType());
            if (writer != null)
            {
                serializer.WriteObject(writer, _testContract);
            }
        }

        outputStream.Position = 0;
        using (
            var conn =
                new SqlConnection(Settings.Default.ConnectionString))
        {
            conn.Open();

            const string INSERT_COMMAND =
                @"INSERT INTO XmlStore (Data) VALUES (@Data)";
            using (var cmd = new SqlCommand(INSERT_COMMAND, conn))
            {
                using (var reader = XmlReader.Create(outputStream))
                {
                    var xml = new SqlXml(reader);

                    cmd.Parameters.Clear();
                    cmd.Parameters.AddWithValue("@Data", xml);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}
于 2009-07-06T18:25:24.987 に答える
1

StringBuilder を使用する Jason w'Serialize 関数を使用しようとしましたが、 [DataContract()] 属性を持つ LingToSQL Designer 生成テーブル クラスに対して空の文字列を返します。

ただし、AgileJon で提案されているようにバイト配列にシリアル化すると

次に、UTF7Encoding を使用して string に変換すると、読み取り可能な XML 文字列が作成されます。

 static string DataContractSerializeUsingByteArray<T>(T obj)
    {
        string sRet = "";
        DataContractSerializer serializer = new DataContractSerializer(typeof(T)); 
        using (MemoryStream memStream = new MemoryStream()) 
        {
            serializer.WriteObject(memStream, obj); 
            byte[] blob = memStream.ToArray(); 
            var encoding= new System.Text.UTF7Encoding();
            sRet = encoding.GetString(blob);
        }
        return sRet;
    } 

stringBuilder ソリューションが機能しない理由がわかりません。

于 2010-03-11T07:07:23.880 に答える
1

XElement に取得する最も効率的な方法についてはわかりませんが、文字列に取得するには、次のように実行します。

DataContractSerializer serializer = new DataContractSerializer(typeof(Foo));
using (MemoryStream memStream = new MemoryStream())
{
    serializer.WriteObject(memStream, fooInstance);
    byte[] blob = memStream.ToArray();
}
于 2009-07-03T04:32:56.690 に答える