Compartilhar via


Tratando o tipo de dados xml e os tipos CLR definidos pelo usuário

Esse recurso será removido em uma versão futura do Microsoft SQL Server. Evite usar esse recurso em desenvolvimentos novos e planeje modificar os aplicativos que atualmente o utilizam.

Nos XML Web Services nativos desde o SQL Server 2005, passar tipos como, por exemplo, o tipo de dados xml ou os tipos CLR (Common Language Runtime) definidos pelo usuário exige algumas tarefas de desenvolvimento adicionais. Este tópico descreve as tarefas que você deve realizar para permitir que os aplicativos baseados em serviços Web funcionem com xml e o tipo de dados CLR definido pelo usuário em métodos Web e consultas parametrizadas.

ObservaçãoObservação

Supõe-se que você tenha um conhecimento básico da implantação dos XML Web Services nativos no SQL Server. Isso inclui a familiarização com tarefas como, por exemplo, criar pontos de extremidade, expor programação SQL como métodos Web e escrever aplicativos do cliente Web para SQL Server que usam outros tipos SQL internos. Caso queira examinar essas informações, consulte Conceitos de XML Web Services Nativos, Implantando XML Web Services Nativos e Práticas recomendadas para usar XML Web Services Nativos.

Tratando o tipo de dados xml em aplicativos do cliente Web

Para que um aplicativo do cliente Web trate corretamente o tipo de dados xml, alguns detalhes dependem de qual destes cenários se aplica:

  • Você está trabalhando com um procedimento armazenado exposto como um método Web em um ponto de extremidade.

  • Você está usando a funcionalidade do lote SQL (sqlbatch) do ponto de extremidade para executar uma consulta parametrizada.

Ambos os cenários exigem que instâncias parametrizadas do tipo de dados xml sejam tratadas usando e preenchendo uma estrutura myEndpoint**::xml**. Nessa estrutura, myEndpoint representa o nome real do ponto de extremidade usado quando instâncias do tipo de dados xml são passadas por meio do código do lado do cliente. Essa estrutura é declarada na classe do proxy da Web do ponto de extremidade.

A estrutura myEndpoint**::xml** é criada quando você adiciona ou atualiza a referência Web para o ponto de extremidade que expõe o método Web no projeto do Visual Studio. No entanto, você precisará preencher a estrutura myEndpoint**::xml** gerada inicialmente na classe do proxy da Web personalizada de acordo com base no uso de XML tipado ou de XML não tipado no código do aplicativo do lado do cliente.

Para instâncias de parâmetro do tipo de dados xml não tipado em métodos Web, a estrutura myEndpoint**::xml** as expõe como uma matriz do tipo System.Xml.XmlNode na classe proxy. Por isso, para passar uma instância de parâmetro do tipo de dados xml, você cria e preenche manualmente uma matriz de nós XML ou usa System.Xml.XmlDocumentFragment para fazer isso. Para obter mais informações, consulte Trabalhando com o tipo de dados xml em aplicativos cliente do Visual Studio.

Para xml tipado em métodos Web, um tipo personalizado é gerado na classe do proxy da Web e nomeado de acordo com o seguinte formato: o nome do método concatenado com a palavra Type e seguido do nome do parâmetro. Por exemplo, se o método Web for exposto usando o nome GetXmlInfo e usar um parâmetro do tipo de dados xml chamado T para passar o XML tipado como entrada, o nome do tipo personalizado exposto na classe do proxy da Web será GetXmlInfoTypeT. Esse tipo personalizado é herdado da estrutura myEndpoint**::xml** e por isso expõe de maneira semelhante o XML tipado como uma matriz de System.Xml.XmlNode.

Tratar o tipo de dados xml em consultas parametrizadas é semelhante a trabalhar com o tipo de dados xml em métodos Web, embora haja uma exceção: o XML tipado deve ser passado do cliente usando o mesmo tipo (myEndpoint**::xml**) usado com o XML não tipado.

Após a preparação da estrutura myEndpoint**::xml**, a instância do tipo de dados xml pode ser exposta como uma matriz de System.Xml.XmlNode dentro da estrutura definida, e isso está presente no objeto SqlParameter.Value.

Uma consulta parametrizada exige a funcionalidade de lote SQL. Isso pode envolver as seguintes preparações adicionais:

  • O ponto de extremidade deve ter o SQL habilitado. Isso significa que BATCHES=ENABLED foi usado quando o ponto de extremidade foi criado ou modificado.

  • Na classe do proxy da Web, o método sqlbatch() será incluído quando uma referência Web for adicionada ou atualizada para um ponto de extremidade habilitado para lote.

Para parâmetros de XML tipado, o método sqlbatch() na classe do proxy da Web é atualizado para incluir a configuração de todas as propriedades adicionais (XmlSchemaCollectionDatabase, XmlSchemaCollectionName, XmlSchemaCollectionOwningSchema) relacionadas com o registro de uma coleção de esquema XML para o objeto System.Data.SqlClient.SqlParameter.

ObservaçãoObservação

Para os métodos Web e as consultas parametrizadas que expõem o tipo de dados xml, em que System.Data.DataSet é retornado na saída (como parte de uma matriz de objetos) e o conteúdo, colocado em DataGrid para visualizar os resultados no aplicativo do cliente, DataSet não usa um tipo de proxy da Web (myEndpoint::xml), e sim o tipo do CLR System.Data.SqlTypes.SqlXml.

Tratando tipos de dados CLR definidos pelo usuário com aplicativos do cliente Web

Para tratar tipos de dados CLR definidos pelo usuário em um aplicativo do cliente Web, você deve completar as seguintes etapas:

  1. Escreva o tipo CLR definido pelo usuário e o compile em uma DLL como, por exemplo, MyType.dll.

    Em Visual Studio 2005, escreva o tipo CLR definido pelo usuário (class ou struct) e o compile em um assembly. O assembly de tipos deve atender aos requisitos do SQL Server para implementar tipos definidos pelo usuário. Isso permite que o assembly seja instalado e registrado em uma instância do SQL Server. Para obter mais informações, consulte "Requisitos para implementação de UDTs" em Tipos CLR definidos pelo usuário.

  2. Para gerar uma DLL complementar do Serializador XML, caso você não tenha implementado IXMLSerializable, execute Sgen.exe na DLL do assembly de tipos. Ela terá um nome como, por exemplo, MyType.XmlSerializers.dll.

    Além de atender aos requisitos básicos para que o tipo CLR definido pelo usuário funcione com o SQL Server, o tipo CLR definido pelo usuário também deve ser serializável em XML para funcionar com os XML Web Services nativos no SQL Server. Para obter mais informações, consulte "Serialização XML" em Tipos CLR definidos pelo usuário.

  3. Instale a DLL do assembly de tipos na instância do SQL Server usando CREATE ASSEMBLY.

    Se não tiver implementado IXMLSerializable e concluído a etapa 2, você também precisará instalar a DLL complementar do Serializador XML na instância do SQL Server usando CREATE ASSEMBLY.

  4. Serialize o tipo CLR definido pelo usuário no XML e o inclua em uma estrutura myEndpoint**::xml** semelhante à descrita na seção anterior.

    Após a instalação do tipo CLR definido pelo usuário no servidor, para passar uma instância desse tipo CLR definido pelo usuário para o SQL Server em um aplicativo do cliente dos XML Web Services nativos, você deve primeiro serializar o tipo CLR definido pelo usuário no formato XML e o incluir em estrutura XML.

    O seguinte código mostra como serializar um tipo CLR definido pelo usuário no formato XML e colocá-lo em um elemento XML (System.Xml.XmlElement).

    // Create the user-defined type class on the client.
    SqlString s = new SqlString("0:0");
    UdtClientApp.Point pnt = Point.Parse(s);
    // Invoke the method and pass in a user-defined type.You will need
    // to convert this to XmlElement before you can pass it to SQL Server.
    System.IO.MemoryStream writer = new System.IO.MemoryStream();
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(UdtClientApp.Point));
    serializer.Serialize(writer, pnt);
    writer.Seek(0, System.IO.SeekOrigin.Begin);
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.Load(writer);
    System.Xml.XmlElement udtXml = xmlDoc.DocumentElement;
    
  5. Dependendo da presença do tipo CLR definido pelo usuário no cliente, você talvez também tenha que desserializar um parâmetro de saída do formato XML do tipo de CLR definido pelo usuário novamente no formato do tipo definido pelo usuário.

    O seguinte código mostra como para desserializar um tipo XML definido pelo usuário novamente para o tipo CLR definido pelo usuário no código do lado do cliente. Neste exemplo, o tipo CLR definido pelo usuário é Point.

    Object[] results = proxy.GetPointUdt(Convert.ToInt16(textBox1.Text), ref udtXml);
    //Deserialze the XML into user-defined type.
    TextReader reader = new StringReader(udtXml.OuterXml);
    // pnt was already defined as UdtClientApp.Point pnt = Point.Parse(s);
    pnt = (UdtClientApp.Point) serializer.Deserialize(reader);
    

    Observe que você não precisa realizar esse processo de desserialização caso esteja usando o tipo CLR definido pelo usuário como XML não tipado no cliente.

Os tipos CLR definidos pelo usuário também podem ser passados para uma consulta parametrizada da mesma forma descrita para o tipo de dados xml. O tipo CLR definido pelo usuário na forma de XML serializado deve ser passado do cliente usando o tipo myEndpoint**::xml**.

Com uma consulta parametrizada que envolve tipos CLR definidos pelo usuário, valores diferentes são definidos na estrutura System.Data.SqlClient.SqlParameter. Por exemplo, as seguintes configurações de propriedade são usadas para tipos CLR definidos pelo usuário:

  • A propriedade SqlDbType deve ser definida como um valor Udt.

  • A propriedade ClrTypeName deve ser definida como o nome qualificado de três partes do SQL Server (MyDatabase**.MySchema.**MyUdtType) do tipo definido pelo usuário instalado como está registrada na instância do SQL Server.