2

DataContractSerializerを介してファイルにシリアル化したかなり大きなオブジェクトグラフがあります。ここで、これらのファイルのリストをユーザーに提示して、選択できるようにします。このリストでは、ルートオブジェクトのプロパティであるファイルに関する詳細の一部を示します。ルートノードのプロパティを表示することだけに関心があるので、グラフ全体をメモリにロードしたくありません。

ファイルからルートオブジェクトをプルして子をスキップできるように、逆シリアル化の「深さ」を制御する方法を知っている人はいますか?他の場所では生のXML操作を行っていないため、ファイルを生のXMLとして扱うことは避けたいと思います。これは、同期を維持する必要があるコードのもう1つのブランチになります。

今の私の唯一のアイデアは、関心のあるプロパティのみを含み、子は含まない互換性のある「summary」オブジェクトを作成し、ファイルをそのオブジェクトに逆シリアル化することです。子はsummaryオブジェクトに関連しないため、これは子をスキップする必要があります。

これを達成するためのより良い方法はありますか?

更新/明確化:属性は私が探している答えではありません。1つには、オブジェクトが最初にシリアル化されたときに「余分な」プロパティがファイルに含まれるのを防ぐことができます。

第二に、彼らは私がやろうとしていることよりも永続的です。最終的には、この時点ではなく、ファイル全体を逆シリアル化したいと思います。ユーザーがインポート用に選択するファイルの要約リストを表示しようとしています。インポート中に、私はすべての子供と孫が必要になります。手順1ではやり過ぎです。これらは潜在的に大きなファイルであるため、ヘッダー情報を表示できるようにいくつかのファイルを完全に逆シリアル化しても機能しません。

うまくいけば、それは元の質問についての混乱を解消します。

4

3 に答える 3

1

ルートノードから詳細を取得したいだけの場合は、最初にXML操作を行うことをお勧めします。別の可能性は、パフォーマンスへの影響はわかりませんが、この問題にDataContractSerializerのバージョン管理機能を使用することです。データ契約で、要約で必要になるフィールドを除くすべてのフィールドをオプションとしてマークします。次に、オプションのフィールドを省略して、データコントラクトを別のクラスとしてコピーします。新しい、より小さなデータコントラクトにデシリアライズします。

class Program
{
    static void Main(string[] args)
    {
        Person a = new Person();
        Person b = new Person();
        a.Name = "Mike";
        b.Name = "Joe";
        b.Parent = a;

        DataContractSerializer dtc = new DataContractSerializer(typeof(Person));

        StringBuilder sb = new StringBuilder();
        using (XmlWriter xr = XmlWriter.Create(sb))
        {
            dtc.WriteObject(xr, b);
        }

        object n;

        DataContractSerializer dtc2 = new DataContractSerializer(typeof(TinyPerson));

        using (XmlReader xr = XmlReader.Create(new StringReader(sb.ToString())))
        {
            n = dtc2.ReadObject(xr);
        }

    }
}

[DataContract(Name="Person")]
public class Person
{
    [DataMember]
    public string Name;

    [DataMember(IsRequired=false)]
    public Person Parent; 
}


[DataContract(Name = "Person")]
public class TinyPerson
{
    [DataMember]
    public string Name;

}
于 2009-01-05T16:54:39.177 に答える
1

それはあなたがそれをしたい方法とほとんど同じです。DataContractSerializerは、概念的には同じであるが、相互にシリアル化するCLRの観点からは異なるタイプを使用する必要があるこの状況を処理することを目的としています。

それを前提として、シリアル化するプロパティの同様のサブセットを使用してオブジェクトを作成し、そのタイプをDataContractSerializerに渡します。

「summary」タイプで、DataContract属性のプロパティ(および公開する子のDataMember属性またはDataContract属性)を設定していることを確認してください。具体的には、NameおよびNamespaceプロパティは、非サマリータイプ(これらは一致する必要があるため)。

于 2009-01-05T15:56:44.143 に答える
-2

属性を使用してシリアル化を制御できます。ここでもっと読む

于 2009-01-05T15:18:15.220 に答える