Pergunta

Eu tenho um gráfico do objeto bastante considerável que eu serializado para um arquivo via DataContractSerializer. Agora eu quero apresentar uma lista desses arquivos para o usuário escolher. Nesta lista, eu quero mostrar alguns dos detalhes sobre o arquivo, que são propriedades do objeto raiz. Eu não quero para carregar todo o gráfico na memória, desde que eu estou interessado apenas em exibindo propriedades do nó raiz.

Alguém sabe uma maneira de controlar a "profundidade" da desserialização para que eu possa basta puxar o objeto raiz do arquivo e saltar sobre as crianças? Eu prefiro evitar tratar o arquivo como XML bruto, desde que eu não estou fazendo quaisquer manipulações XML brutos em qualquer outro lugar, e que seria mais um ramo de código que eu tenho que manter em sincronia.

Minha única idéia agora é criar um objeto compatível "Resumo" contendo apenas as propriedades que eu estou interessado, e nenhuma das crianças, e anular o arquivo para isso. Isso deve ignorar as crianças, uma vez que não são relevantes para o objeto sumário.

Existe uma maneira melhor de fazer isso?

Update / Esclarecimento : atributos não são a resposta que eu estou procurando. Por um lado, eles vão impedir que as propriedades "extra" de acabar no arquivo quando o objeto foi serializado em primeiro lugar.

Em segundo lugar, eles são mais permanentes do que o que estou tentando fazer. Eventualmente, eu quero desserializar o arquivo inteiro, não apenas neste momento. Eu estou tentando mostrar uma lista resumida de arquivos que o usuário irá escolher para importação. Durante a importação, eu vou precisar de todos os filhos e netos. É apenas um exagero durante o passo 1. Estes são arquivos potencialmente grandes, tão plenamente deserializing vários deles apenas para que eu possa exibir suas informações de cabeçalho não está indo para o trabalho.

Espero que apura-se qualquer confusão sobre a pergunta original.

Foi útil?

Solução

Isso é muito bonito o jeito que você quiser fazê-lo. O DataContractSerializer destina-se a lidar com esta situação, onde você tem que tipos que são conceitualmente o mesmo, mas tipos diferentes do ponto de vista do CLR qual deseja serialize um no outro.

Tendo em conta que, basta criar o objeto com o subconjunto semelhante de propriedades que deseja serialize e passar esse tipo para o DataContractSerializer.

Certifique-se que sobre o tipo "Resumo" que defina as propriedades do atributo DataContract (bem como quaisquer atributos DataMember ou atributos DataContract sobre as crianças que você expõem), especificamente as propriedades Name e Namespace para refletir o nome e namespace de do tipo não-resumo (uma vez que estes devem combinar).

Outras dicas

A minha primeira recomendação seria fazer a manipulação de XML se você quiser apenas para retirar alguns detalhes do nó raiz. Outra possibilidade, embora eu não sei as implicações performace, é usar os recursos de controle de versão de DataContractSerializer para este problema. Em seu contrato de dados, marcar todos os campos, exceto aqueles que você vai precisar no resumo como opcional. Em seguida, copie o contrato de dados como uma outra classe, deixando de fora os campos opcionais. Desserializar para o novo contrato de dados, menor.

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;

}

Você pode controlar sua serialização usando atributos. leia mais aqui

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top