Tipos de XML e ADO.NET em contratos de dados

O modelo de contrato de dados do WCF (Windows Communication Foundation) permite determinados tipos que representam o XML diretamente. Quando esses tipos são serializados para XML, o serializador grava o conteúdo XML desses tipos sem nenhum processamento adicional. Os tipos compatíveis são XmlElement, matrizes XmlNode (mas não do tipo XmlNode em si), bem como tipos que implementam IXmlSerializable. O tipo DataSet e DataTable, bem como conjuntos de dados tipado, são comumente usados na programação de banco de dados. Esses tipos implementam a interface IXmlSerializable e, portanto, são serializáveis no modelo de contrato de dados. Algumas considerações especiais para esses tipos são listadas no final deste tópico.

Tipos XML

Elemento XML

O tipo XmlElement é serializado usando seu conteúdo XML. Por exemplo, usando o tipo a seguir.

[DataContract(Namespace=@"http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlElement myDataMember;
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        myDataMember = xd.CreateElement("myElement");
        myDataMember.InnerText = "myContents";
        myDataMember.SetAttribute
         ("myAttribute","myValue");
    }
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
    <DataMember()> _
    Public myDataMember As XmlElement

    Public Sub TestClass()
        Dim xd As New XmlDocument()
        myDataMember = xd.CreateElement("myElement")
        myDataMember.InnerText = "myContents"
        myDataMember.SetAttribute("myAttribute", "myValue")

    End Sub
End Class

Isso é serializado para XML da seguinte maneira:

<MyDataContract xmlns="http://schemas.contoso.com">  
    <myDataMember>  
        <myElement xmlns="" myAttribute="myValue">  
            myContents  
        </myElement>  
    </myDataMember>  
</MyDataContract>  

Observe que um elemento <myDataMember> de membro de dados wrapper ainda está presente. Não há como remover esse elemento no modelo de contrato de dados. Os serializadores que manipulam esse modelo (o DataContractSerializer e NetDataContractSerializer) podem emitir atributos especiais nesse elemento wrapper. Esses atributos incluem o atributo padrão da Instância de Esquema XML "zero" (permitindo que XmlElement seja null) e o atributo "type" (permitindo que XmlElement seja usado polimorficamente). Além disso, os seguintes atributos XML são específicos do WCF: "Id", "Ref", "Type" e "Assembly". Esses atributos podem ser emitidos para permitir o uso de XmlElement com o modo de preservação do grafo de objetos habilitado ou com o NetDataContractSerializer. (Para obter mais informações sobre o modo de preservação do grafo de objeto, consulte Serialização e Desserialização.)

Matrizes ou coleções de XmlElement são permitidas e são tratadas como qualquer outra matriz ou coleção. Ou seja, há um elemento wrapper para toda a coleção e um elemento wrapper separado (semelhante ao <myDataMember> exemplo anterior) para cada XmlElement na matriz.

Na desserialização, um XmlElement é criado pelo desserializador do XML de entrada. Um pai XmlDocument válido é fornecido pelo desserializador.

Verifique se o fragmento XML desserializado para um XmlElement define todos os prefixos que ele usa e não depende de nenhuma definição de prefixo de elementos ancestrais. Essa é uma preocupação somente ao usar o DataContractSerializer para acessar o XML de uma origem diferente (não DataContractSerializer).

Quando usado com o DataContractSerializer, o XmlElement pode ser atribuído polimorficamente, mas apenas a um membro de dados do tipo Object. Mesmo que ele implemente IEnumerable, um XmlElement não pode ser usado como um tipo de coleção e não pode ser atribuído a um membro de dados IEnumerable. Assim como acontece com todas as atribuições polimórficas, o DataContractSerializer emite o contrato de dados no XML resultante. Nesse caso, é "XmlElement" no namespace http://schemas.datacontract.org/2004/07/System.Xml.

Com NetDataContractSerializer, qualquer atribuição polimórfica válida de XmlElement (para Object ou IEnumerable) é compatível.

Não tente usar nenhum dos serializadores com tipos derivados de XmlElement, sejam eles atribuídos polimorficamente ou não.

Matriz de XmlNode

Usar matrizes de XmlNode é muito semelhante a usar XmlElement. Usar matrizes de XmlNode oferece mais flexibilidade do que usar XmlElement. Você pode escrever vários elementos dentro do elemento de encapsulamento do membro de dados. Você também pode injetar conteúdo diferente de elementos dentro do elemento de encapsulamento do membro de dados, como comentários XML. Por fim, você pode colocar atributos no elemento de membro de dados de encapsulamento. Tudo isso pode ser obtido preenchendo a matriz de XmlNode com classes derivadas específicas de XmlNode, como XmlAttribute, XmlElement ou XmlComment. Por exemplo, usando o tipo a seguir.

[DataContract(Namespace="http://schemas.contoso.com")]
public class MyDataContract
{
    [DataMember]
    public XmlNode[] myDataMember = new XmlNode[4];
    public void TestClass()
    {
        XmlDocument xd = new XmlDocument();
        XmlElement xe = xd.CreateElement("myElement");
        xe.InnerText = "myContents";
        xe.SetAttribute
         ("myAttribute","myValue");
    
        XmlAttribute atr = xe.Attributes[0];
        XmlComment cmnt = xd.CreateComment("myComment");
        
      myDataMember[0] = atr;
      myDataMember[1] = cmnt;
      myDataMember[2] = xe;
      myDataMember[3] = xe;
    }
}
<DataContract([Namespace]:="http://schemas.contoso.com")> _
Public Class MyDataContract
    <DataMember()> _
    Public myDataMember(3) As XmlNode

    Public Sub TestClass()
        Dim xd As New XmlDocument()
        Dim xe As XmlElement = xd.CreateElement("myElement")
        xe.InnerText = "myContents"
        xe.SetAttribute("myAttribute", "myValue")

        Dim atr As XmlAttribute = xe.Attributes(0)
        Dim cmnt As XmlComment = xd.CreateComment("myComment")

        myDataMember(0) = atr
        myDataMember(1) = cmnt
        myDataMember(2) = xe
        myDataMember(3) = xe

    End Sub

End Class

Quando serializado, o XML resultante é semelhante ao código a seguir.

<MyDataContract xmlns="http://schemas.contoso.com">  
  <myDataMember myAttribute="myValue">  
     <!--myComment-->  
     <myElement xmlns="" myAttribute="myValue">  
 myContents  
     </myElement>  
     <myElement xmlns="" myAttribute="myValue">  
       myContents  
     </myElement>  
  </myDataMember>  
</MyDataContract>  

Observe que o <myDataMember> do elemento wrapper do membro de dados contém um atributo, um comentário e dois elementos. Estas são as quatro instâncias XmlNode que foram serializadas.

Uma matriz de XmlNode resulta em XML inválido não pode ser serializado. Por exemplo, uma matriz de duas instâncias XmlNode, em que a primeira é um XmlElement e a segunda é um XmlAttribute inválido, pois essa sequência não corresponde a nenhuma instância XML válida (não há lugar para anexar o atributo).

Na desserialização de uma matriz de XmlNode, os nós são criados e preenchidos com informações do XML de entrada. Um pai XmlDocument válido é fornecido pelo desserializador. Todos os nós são desserializados, incluindo todos os atributos no elemento membro de dados wrapper, mas excluindo os atributos colocados lá pelos serializadores do WCF (como os atributos usados para indicar a atribuição polimórfica). A restrição sobre a definição de todos os prefixos de namespace no fragmento XML se aplica à desserialização de matrizes de XmlNode, da mesma forma que faz para desserializar XmlElement.

Ao usar os serializadores com a preservação do grafo de objeto ativada, a igualdade de objetos só é preservada no nível das matrizes XmlNode, não em instâncias individuais XmlNode.

Não tente serializar uma matriz de XmlNode, em um ou mais nós estão definidos como null. É permitido que todo o membro da matriz seja null, mas não para qualquer XmlNode individual contido na matriz. Se todo o membro da matriz for nulo, o elemento membro de dados wrapper conterá um atributo especial que indica que ele é nulo. Na desserialização, todo o membro da matriz também se torna nulo.

Somente matrizes regulares de XmlNode são tratadas especialmente pelo serializador. Os membros de dados declarados como outros tipos de coleção que contêm XmlNode, ou membros de dados declarados como matrizes de tipos derivados de XmlNode, não são tratados especialmente. Portanto, eles normalmente não são serializáveis, a menos que também atendam a um dos outros critérios para serialização.

Matrizes ou coleções de matrizes de XmlNode são permitidas. Há um elemento wrapper para toda a coleção e um elemento wrapper separado (semelhante ao <myDataMember> no exemplo anterior) para cada matriz de XmlNode na matriz externa ou coleção.

Preencher um membro de dados do tipo Array de Object ou Array de IEnumerable com instâncias XmlNode não resulta no membro de dados sendo tratado como instâncias Array de XmlNode. Cada membro da matriz é serializado separadamente.

Quando usado com o DataContractSerializer, as matrizes de XmlNode podem ser atribuídas polimorficamente, mas apenas a um membro de dados do tipo Object. Mesmo que ela implemente IEnumerable, uma matriz de XmlNode não pode ser usada como um tipo de coleção nem ser atribuída a um membro de dados IEnumerable. Assim como acontece com todas as atribuições polimórficas, o DataContractSerializer emite o contrato de dados no XML resultante – nesse caso, é "XmlElement" no namespace http://schemas.datacontract.org/2004/07/System.Xml. Quando usado com o NetDataContractSerializer, qualquer atribuição válida de uma matriz XmlNode é compatível.

Considerações sobre esquema

Para obter detalhes sobre o mapeamento de esquema de tipos XML, consulte Referência de esquema de contrato de dados. Esta seção fornece um resumo dos pontos importantes.

Um membro de dados do tipo XmlElement é mapeado para um elemento definido usando o tipo anônimo a seguir.

<xsd:complexType>  
   <xsd:sequence>  
      <xsd:any minOccurs="0" processContents="lax" />  
   </xsd:sequence>  
</xsd:complexType>  

Um membro de dados da matriz do tipo XmlNode é mapeado para um elemento definido usando o tipo anônimo a seguir.

<xsd:complexType mixed="true">  
   <xsd:sequence>  
      <xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />  
   </xsd:sequence>  
   <xsd:anyAttribute/>  
</xsd:complexType>  

Tipos que implementam a interface IXmlSerialable

Os tipos que implementam a interface IXmlSerializable têm compatibilidade total pelo DataContractSerializer. O atributo XmlSchemaProviderAttribute deve ser sempre aplicado a esses tipos para controlar seu esquema.

Há três variedades de tipos que implementam IXmlSerializable: tipos que representam conteúdo arbitrário, tipos que representam um único elemento e tipos DataSet herdados.

  • Os tipos de conteúdo usam um método de provedor de esquema especificado pelo atributo XmlSchemaProviderAttribute. O método não retorna null e a propriedade IsAny no atributo é deixada no valor padrão de false. Esse é o uso mais comum de tipos IXmlSerializable.

  • Os tipos de elemento são usados quando um tipo IXmlSerializable precisa controlar seu próprio nome de elemento raiz. Para marcar um tipo como um tipo de elemento, defina a propriedade IsAny no atributo XmlSchemaProviderAttribute como true ou retorne nulo do método do provedor de esquema. Ter um método de provedor de esquema é opcional para tipos de elemento. Você pode especificar nulo em vez do nome do método no XmlSchemaProviderAttribute. No entanto, se IsAny for true e um método de provedor de esquema for especificado, o método deverá retornar nulo.

  • Tipos herdados DataSet são tipos IXmlSerializable que não são marcados com o atributo XmlSchemaProviderAttribute. Em vez disso, eles dependem do método GetSchema para geração de esquema. Esse padrão é usado para o tipo DataSet e seu conjunto de dados tipado deriva uma classe em versões anteriores do .NET Framework, mas agora está obsoleto e tem compatibilidade apenas por motivos herdados. Não confie nesse padrão e sempre aplique o XmlSchemaProviderAttribute aos seus tipos IXmlSerializable.

Tipos de conteúdo IXmlSerializable

Ao serializar um membro de dados de um tipo que implementa IXmlSerializable e é um tipo de conteúdo conforme definido anteriormente, o serializador grava o elemento wrapper para o membro de dados e passa o controle para o método WriteXml. A implementação de WriteXml pode gravar qualquer XML, incluindo a adição de atributos ao elemento wrapper. Depois que WriteXml é concluído, o serializador fecha o elemento.

Ao desserializar um membro de dados de um tipo que implementa IXmlSerializable e é um tipo de conteúdo conforme definido anteriormente, o desserializador posiciona o leitor XML no elemento wrapper para o membro de dados e passa o controle para o método ReadXml. O método precisa ler todo o elemento, incluindo as marcas inicial e final. Verifique se o código ReadXml manipula o caso em que o elemento está vazio. Além disso, sua implementação de ReadXml não deve depender do elemento wrapper que está sendo nomeado de uma maneira específica. O nome escolhido pelo serializador pode variar.

É permitido atribuir tipos de conteúdo IXmlSerializable polimorficamente, por exemplo, a membros de dados do tipo Object. Também é permitido que as instâncias de tipo sejam nulas. Por fim, é possível usar tipos IXmlSerializable com a preservação do grafo de objeto habilitada e com o NetDataContractSerializer. Todos esses recursos exigem que o serializador WCF anexe determinados atributos ao elemento wrapper ("nil" e "type" no namespace da Instância de Esquema XML e "Id", "Ref", "Type" e "Assembly" em um namespace específico do WCF).

Atributos a serem ignorados ao implementar ReadXml

Antes de passar o controle para o código ReadXml, o desserializador examina o elemento XML, detecta esses atributos XML especiais e atua neles. Por exemplo, se "nil" for true, um valor nulo será desserializado e ReadXml não será chamado. Se o polimorfismo for detectado, o conteúdo do elemento será desserializado como se fosse um tipo diferente. A implementação do tipo atribuído polimorficamente de ReadXml é chamada. De qualquer forma, uma implementação ReadXml deve ignorar esses atributos especiais porque eles são tratados pelo desserializador.

Considerações de esquema para tipos de conteúdo IXmlSerializable

Ao exportar o esquema de um tipo de conteúdo IXmlSerializable, o método do provedor de esquema é chamado. Um XmlSchemaSet é passado para o método do provedor de esquema. O método pode adicionar qualquer esquema válido ao conjunto de esquemas. O conjunto de esquemas contém o esquema que já é conhecido no momento em que ocorre a exportação de esquema. Quando o método do provedor de esquema precisa adicionar um item ao conjunto de esquemas, ele precisa determinar se já existe um XmlSchema com o namespace apropriado no conjunto. Se isso acontecer, o método do provedor de esquema precisa adicionar o novo item ao XmlSchema existente. Caso contrário, ele precisa criar uma nova instância XmlSchema. Isso é importante se matrizes de tipos IXmlSerializable estiverem sendo usadas. Por exemplo, se você tiver um tipo IXmlSerializable exportado como tipo "A" no namespace "B", é possível que, quando o método do provedor de esquema for chamado, o esquema já contenha o esquema de "B" para manter o tipo "ArrayOfA".

Além de adicionar tipos ao XmlSchemaSet, o método de provedor de esquema para tipos de conteúdo precisa retornar um valor não nulo. Ele pode retornar um XmlQualifiedName que especifica o nome do tipo de esquema a ser usado para o tipo IXmlSerializable fornecido. Esse nome qualificado também serve como o nome e o namespace do contrato de dados para o tipo. É permitido retornar um tipo que não existe no esquema definido imediatamente quando o método do provedor de esquema retorna. No entanto, espera-se que, quando todos os tipos relacionados forem exportados (o método Export é chamado para todos os tipos relevantes no XsdDataContractExporter e a Schemas propriedade é acessada), o tipo exista no conjunto de esquemas. Acessar a propriedade Schemas antes que todas as chamadas Export relevantes tenham sido feitas pode resultar em um XmlSchemaException. Para obter mais informações sobre o processo de exportação, consulte Exportando esquemas de classes.

O método do provedor de esquema também pode retornar o XmlSchemaType para usar. O tipo pode ou não ser anônimo. Se for anônimo, o esquema do tipo IXmlSerializable será exportado como um tipo anônimo sempre que o tipo IXmlSerializable for usado como membro de dados. O tipo IXmlSerializable ainda tem um namespace e um nome de contrato de dados. (Isso é determinado conforme descrito em Nomes de Contrato de Dados , exceto que o atributo DataContractAttribute não pode ser usado para personalizar o nome.) Se não for anônimo, ele precisará ser um dos tipos no XmlSchemaSet. Esse caso é equivalente a retornar o XmlQualifiedName do tipo.

Além disso, uma declaração de elemento global é exportada para o tipo. Se o tipo não tiver o atributo XmlRootAttribute aplicado a ele, o elemento terá o mesmo nome e namespace que o contrato de dados e sua propriedade "nillable" será true. A única exceção a isso é o namespace de esquema (http://www.w3.org/2001/XMLSchema). Se o contrato de dados do tipo estiver nesse namespace, o elemento global correspondente estará no namespace em branco porque é proibido adicionar novos elementos ao namespace de esquema. Se o tipo tiver o atributo XmlRootAttribute aplicado a ele, a declaração de elemento global será exportada usando as seguintes propriedades: ElementName, Namespace e IsNullable. Os padrões com XmlRootAttribute aplicados são o nome do contrato de dados, um namespace em branco e "nillable" sendo verdadeiro.

As mesmas regras de declaração de elemento global se aplicam aos tipos de conjunto de dados herdados. Observe que não é possível substituir declarações XmlRootAttribute de elemento global adicionadas por meio de código personalizado, adicionadas ao XmlSchemaSet usando o método de provedor de esquema ou por meio de GetSchema para tipos de conjunto de dados herdados.

Tipos de elemento IXmlSerializable

os tipos de elemento IXmlSerializable têm a propriedade IsAny definida como true ou têm o método de provedor de esquema retornado null.

Serializar e desserializar um tipo de elemento é muito semelhante à serialização e desserialização de um tipo de conteúdo. No entanto há algumas diferenças importantes:

  • Espera-se que a implementação de WriteXml grave exatamente um elemento (que, naturalmente, poderia conter vários elementos filho). Ele não deve escrever atributos fora desse único elemento, vários elementos irmãos ou conteúdo misto. O elemento pode estar vazio.

  • A implementação de ReadXml não deve ler o elemento wrapper. Espera-se que ele leia o único elemento que WriteXml produz.

  • Ao serializar um tipo de elemento regularmente (por exemplo, como um membro de dados em um contrato de dados), o serializador gera um elemento wrapper antes de chamar WriteXml, como acontece com os tipos de conteúdo. No entanto, ao serializar um tipo de elemento no nível superior, o serializador normalmente não gera um elemento wrapper em torno do elemento que WriteXml grava, a menos que um nome raiz e namespace tenham sido explicitamente especificados ao construir o serializador nos construtores DataContractSerializer ou NetDataContractSerializer. Para obter mais informações, consulte Serialização e Desserialização.

  • Ao serializar um tipo de elemento no nível superior sem especificar o nome raiz e o namespace em tempo de construção, WriteStartObject e WriteEndObject essencialmente não fazem nada e WriteObjectContent chama WriteXml. Nesse modo, o objeto que está sendo serializado não pode ser nulo e não pode ser atribuído polimorficamente. Além disso, a preservação do grafo de objeto não pode ser habilitada e não NetDataContractSerializer pode ser usado.

  • Ao desserializar um tipo de elemento no nível superior sem especificar o nome raiz e o namespace em tempo de construção, IsStartObject retornará true se ele puder encontrar o início de qualquer elemento. ReadObject com o parâmetro definido verifyObjectName para true se comporta da mesma maneira que IsStartObject antes de realmente ler o objeto. ReadObject, em seguida, passa o controle para o método ReadXml.

O esquema exportado para tipos de elemento é o mesmo que para o tipo XmlElement descrito em uma seção anterior, exceto que o método do provedor de esquema pode adicionar qualquer esquema adicional ao XmlSchemaSet como tipo de conteúdo. O uso do atributo XmlRootAttribute com tipos de elemento não é permitido, e declarações de elemento global nunca são emitidas para esses tipos.

Diferenças do XmlSerializer

A interface IXmlSerializable e os atributos XmlSchemaProviderAttribute e XmlRootAttribute são também reconhecidos pelo XmlSerializer. No entanto, há algumas diferenças na forma como elas são tratadas no modelo de contrato de dados. As diferenças importantes estão resumidas a seguir:

  • O método do provedor de esquema precisa ser público para ser utilizável no XmlSerializer, mas não no modelo de contrato de dados.

  • O método do provedor de esquema é chamado quando IsAny é verdadeiro no modelo de contrato de dados, mas não com o XmlSerializer.

  • Quando o atributo XmlRootAttribute não está presente para tipos de conteúdo ou conjunto de dados herdados, o XmlSerializer exporta uma declaração do elemento global no namespace em branco. No modelo de contrato de dados, o namespace usado normalmente é o namespace do contrato de dados, conforme descrito anteriormente.

Lembre-se dessas diferenças ao criar tipos usados com ambas as tecnologias de serialização.

Importando esquema IXmlSerializable

Ao importar um esquema gerado de tipos IXmlSerializable, há algumas possibilidades:

  • O esquema gerado pode ser um esquema de contrato de dados válido, conforme descrito na Referência de Esquema de Contrato de Dados. Nesse caso, o esquema pode ser importado como de costume e tipos de contrato de dados regulares são gerados.

  • O esquema gerado pode não ser um esquema de contrato de dados válido. Por exemplo, seu método de provedor de esquema pode gerar um esquema que envolve atributos XML que não têm compatibilidade no modelo de contrato de dados. Nesse caso, você pode importar o esquema como tipos IXmlSerializable. Esse modo de importação não está ativado por padrão, mas pode ser facilmente habilitado – por exemplo, com a opção de linha de comando /importXmlTypes para a Ferramenta de Utilitário de Metadados do ServiceModel (Svcutil.exe). Isso é descrito em detalhes em Importando esquemas para gerar classes. Observe que você precisa trabalhar diretamente com o XML para suas instâncias de tipo. Você também pode considerar o uso de uma tecnologia de serialização diferente que permite uma gama mais ampla de esquemas. Veja o tópico sobre como usar o XmlSerializer.

  • Talvez você queira reutilizar seus tipos IXmlSerializable existentes no proxy em vez de gerar novos. Nesse caso, o recurso de tipos referenciados descrito no tópico “Importar esquema para gerar tipos” pode ser usado para indicar o tipo a ser reutilizado. Isso corresponde ao uso da opção /reference no svcutil.exe, que especifica o assembly que contém os tipos a serem reutilizados.

Representando XML arbitrário em contratos de dados

O XmlElement, a matriz XmlNode e os tipos IXmlSerializable permitem injetar XML arbitrário no modelo de contrato de dados. O DataContractSerializer e NetDataContractSerializer passam esse conteúdo XML para o gravador XML em uso, sem interferir no processo. No entanto, os gravadores XML podem impor determinadas restrições ao XML que eles gravam. Especificamente, veja alguns exemplos importantes:

  • Os gravadores XML normalmente não permitem uma declaração de documento XML (por exemplo, <?xml version='1.0' ?>) no meio da gravação de outro documento. Você não pode pegar um documento XML completo e serializá-lo como um Array do membro de dados XmlNode. Para fazer isso, você precisa remover a declaração do documento ou usar seu próprio esquema de codificação para representá-la.

  • Todos os gravadores XML fornecidos com o WCF rejeitam instruções de processamento XML (<? ... ?>) e definições de tipo de documento (<! ... >), porque elas não são permitidas em mensagens SOAP. Novamente, você pode usar seu próprio mecanismo de codificação para contornar essa restrição. Se você precisar incluí-los no XML resultante, você poderá escrever um codificador personalizado que usa gravadores XML que permitem eles.

  • Ao implementar WriteXml, evite chamar o método WriteRaw no gravador XML. O WCF usa uma variedade de codificações XML (incluindo binária), é muito difícil ou impossível usar WriteRaw de modo que o resultado seja utilizável em qualquer codificação.

  • Ao implementar WriteXml, evite usar os métodos WriteEntityRef e WriteNmToken que não são compatíveis com os gravadores XML fornecidos com o WCF.

Usando DataSet, DataSet Digitado e DataTable

O uso desses tipos é totalmente compatível com o modelo de contrato de dados. Ao usar domínios personalizados, considere os seguintes pontos:

  • O esquema para esses tipos (especialmente DataSet e suas classes derivadas tipadas) pode não ser interoperável com algumas plataformas não WCF ou resultar em baixa usabilidade com essas plataformas. Além disso, o uso do tipo DataSet pode ter implicações de desempenho. Por fim, isso pode dificultar a versão do aplicativo no futuro. Considere usar tipos de contrato de dados explicitamente definidos em vez de tipos DataSet nos seus contratos.

  • Ao importar o esquema DataSet ou DataTable, é importante fazer referência a esses tipos. Com a ferramenta de linha de comando Svcutil.exe, isso pode ser feito passando o nome do assembly System.Data.dll para a opção /reference. Se estiver importando o esquema de conjunto de dados tipado, você deverá referenciá-lo. Com Svcutil.exe, passe o local do assembly do conjunto de dados tipado para a opção /reference . Para obter mais informações sobre tipos de referência, consulte Importando esquema para gerar classes.

A compatibilidade para DataSets tipados no modelo de contrato de dados é limitada. DataSets tipoados podem ser serializados e desserializados e podem exportar seu esquema. No entanto, a importação de esquema do Contrato de Dados não pode gerar novos tipos de Conjunto de Dados tipado do esquema, pois ele só pode reutilizar os existentes. Você pode apontar para um DataSet tipado existente usando a opção /r no Svcutil.exe. Se você tentar usar um Svcutil.exe sem a opção /r em um serviço que usa um conjunto de dados tipado, um serializador alternativo (XmlSerializer) será selecionado automaticamente. Se você precisar usar o DataContractSerializer e gerar DataSets do esquema, poderá usar o seguinte procedimento: gerar os tipos de DataSets tipado (usando a ferramenta Xsd.exe com a opção /d no serviço), compilar os tipos e, em seguida, apontá-los usando a opção /r no Svcutil.exe.

Confira também