Share via


Gestione del tipo di dati xml e dei tipi CLR definiti dall'utente

Questa caratteristica verrà rimossa a partire da una delle prossime versioni di Microsoft SQL Server. Evitare di utilizzare questa caratteristica in un nuovo progetto di sviluppo e prevedere interventi di modifica nelle applicazioni in cui è attualmente implementata.

A partire da SQL Server 2005 nei servizi Web XML nativi per passare nuovi tipi di dati quali il tipo di dati xml o i tipi CLR definiti dall'utente, è necessario eseguire alcune attività di sviluppo aggiuntive. In questo argomento vengono descritte le attività che è necessario eseguire per consentire alle applicazioni basate su servizi Web XML di utilizzare i tipi di dati xml e CLR definiti dall'utente nei metodi Web e nelle query con parametri.

Nota

Si presume che sia stata acquisita una conoscenza di base della distribuzione dei servizi Web XML nativi in SQL Server, incluse le attività quali la creazione di endpoint, l'esposizione della programmabilità SQL sotto forma di metodi Web e la scrittura di applicazioni client Web di base per SQL Server che utilizzano altri tipi SQL predefiniti. Per informazioni su queste attività, vedere Concetti relativi ai servizi Web XML nativi, Distribuzione di servizi Web XML nativi e Procedure consigliate per l'utilizzo dei Servizi Web XML nativi.

Gestione del tipo di dati xml nelle applicazioni client Web

Per gestire correttamente il tipo di dati xml nelle applicazioni client Web, è necessario innanzitutto stabilire in quale degli scenari seguenti ci si trova:

  • Si utilizza una stored procedure esposta come un metodo Web in un endpoint.

  • Si utilizza la funzionalità per i batch SQL (sqlbatch) dell'endpoint per eseguire una query con parametri.

In entrambi gli scenari, per gestire le istanze con parametri del tipo di dati xml è necessario utilizzare e compilare una struttura myEndpoint**::xml**. Nella struttura, myEndpoint rappresenta il nome effettivo dell'endpoint utilizzato quando le istanze del tipo di dati xml vengono passate tramite il codice sul lato client. Questa struttura viene dichiarata nella classe proxy Web dell'endpoint.

La struttura myEndpoint**::xml** viene creata quando si aggiunge o si aggiorna il riferimento Web all'endpoint che espone il metodo Web nel progetto di Visual Studio. Sarà tuttavia necessario compilare in modo appropriato la struttura myEndpoint**::xml** iniziale generata nella classe proxy Web personalizzata, a seconda che nel codice dell'applicazione sul lato client si utilizzi codice XML tipizzato o non tipizzato.

Le istanze dei parametri con tipo di dati xml non tipizzato nei metodi Web vengono esposte dalla struttura myEndpoint**::xml** come una matrice di tipo System.Xml.XmlNode nella classe proxy. Per passare un'istanza del parametro con il tipo di dati xml, è pertanto necessario creare e riempire manualmente una matrice di nodi XML o, preferibilmente, utilizzare System.Xml.XmlDocumentFragment per eseguire questa operazione. Per ulteriori informazioni, vedere Utilizzo del tipo di dati XML nelle applicazioni client di Visual Studio.

Per i dati xml tipizzati nei metodi Web, nella classe proxy Web viene generato un tipo personalizzato al quale viene assegnato un nome composto dal nome del metodo concatenato con la parola Type e quindi seguito dal nome del parametro. Ad esempio, se il metodo Web viene esposto con il nome GetXmlInfo e contiene un parametro con tipo di dati xml denominato T per il passaggio di codice XML tipizzato come input, il nome del tipo personalizzato esposto nella classe proxy Web sarà GetXmlInfoTypeT. Il tipo personalizzato eredita dalla struttura myEndpoint**::xml**, pertanto espone allo stesso modo il codice XML tipizzato come una matrice di System.Xml.XmlNode.

La gestione del tipo di dati xml nelle query con parametri è simile all'utilizzo del tipo di dati xml nei metodi Web, con un'unica eccezione rappresentata dal fatto che il codice XML tipizzato deve essere passato dal client tramite lo stesso tipo (myEndpoint**::xml**) utilizzato con il codice XML non tipizzato.

Dopo avere preparato la struttura myEndpoint**::xml**, è possibile esporre l'istanza del tipo di dati xml come una matrice di System.Xml.XmlNode all'interno della struttura definita, che a sua volta viene inclusa nell'oggetto SqlParameter.Value.

Una query con parametri richiede la funzionalità per i batch SQL e ciò può implicare i processi di preparazione aggiuntivi seguenti:

  • Per l'endpoint deve essere stato attivato SQL. Ciò significa che quando l'endpoint viene creato o modificato, viene utilizzato BATCHES=ENABLED.

  • Nella classe proxy Web verrà incluso il metodo sqlbatch() quando viene aggiunto o aggiornato un riferimento Web per un endpoint abilitato per i batch.

Per i parametri XML tipizzati, il metodo sqlbatch() della classe proxy Web viene aggiornato in modo da includervi le impostazioni delle eventuali proprietà aggiuntive (XmlSchemaCollectionDatabase, XmlSchemaCollectionName, XmlSchemaCollectionOwningSchema) correlate alla registrazione di un insieme di schemi XML per l'oggetto System.Data.SqlClient.SqlParameter.

Nota

Per i metodi Web e le query con parametri che espongono il tipo di dati xml, dove nell'output viene restituito un valore System.Data.DataSet (come parte di una matrice di oggetti) e il relativo contenuto viene posizionato in un DataGrid per visualizzare i risultati nell'applicazione client, DataSet non utilizza un tipo di proxy Web (myEndpoint::xml) ma utilizza invece il tipo CLR System.Data.SqlTypes.SqlXml.

Gestione di tipi CLR definiti dall'utente con le applicazioni client Web

Per gestire i tipi CLR definiti dall'utente in un'applicazione client Web, è necessario eseguire la procedura seguente:

  1. Scrivere il tipo CLR definito dall'utente e compilarlo in una DLL, ad esempio MyType.dll.

    In Visual Studio 2005, scrivere il tipo CLR definito dall'utente (class o struct) e compilarlo in un assembly. L'assembly per il tipo deve essere conforme ai requisiti di SQL Server per l'implementazione di tipi definiti dall'utente. Ciò consente di installare e registrare l'assembly in un'istanza di SQL Server. Per ulteriori informazioni, vedere la sezione relativa ai requisiti per l'implementazione di tipi UDT in Tipi CLR definiti dall'utente.

  2. Per creare una DLL complementare del serializzatore XML, se non è stato implementato IXMLSerializable, eseguire Sgen.exe sulla DLL dell'assembly per il tipo. Assegnare alla DLL un nome, ad esempio MyType.XmlSerializers.dll.

    Oltre a soddisfare i requisiti di base dei tipi CLR definiti dall'utente per poter essere utilizzato con SQL Server, il tipo CLR definito dall'utente deve inoltre essere compatibile con la serializzazione XML per poter essere utilizzato con i servizi Web XML nativi di SQL Server. Per ulteriori informazioni, vedere la sezione relativa alla serializzazione XML in Tipi CLR definiti dall'utente.

  3. Installare la DLL dell'assembly per il tipo nell'istanza di SQL Server tramite CREATE ASSEMBLY.

    Se non è stato implementato IXMLSerializable ed è stato completato il passaggio 2, sarà inoltre necessario installare la DLL complementare del serializzatore XML nell'istanza di SQL Server tramite CREATE ASSEMBLY.

  4. Serializzare il tipo CLR definito dall'utente e includerlo in una struttura myEndpoint**::xml** simile a quella decritta nella sezione precedente.

    Dopo avere installato il tipo CLR definito dall'utente nel server, per passare un'istanza di tale tipo a SQL Server da un'applicazione client dei servizi Web XML nativi, è necessario innanzitutto serializzare il tipo CLR definito dall'utente in formato XML e includerlo in una strutturaXML.

    Il codice seguente illustra la serializzazione di un tipo CLR definito dall'utente nel formato XML e il relativo inserimento in un 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. A seconda del tipo CLR definito dall'utente presente nel client, potrebbe inoltre essere necessario deserializzare un parametro di output dal formato XML al formato del relativo tipo definito dall'utente.

    Il codice seguente illustra la deserializzazione del codice XML del tipo definito dall'utente al tipo CLR definito dall'utente nel codice sul lato client. In questo esempio, il tipo CLR definito dall'utente è 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);
    

    Si noti che non è necessario eseguire la deserializzazione se si utilizza il tipo CLR definito dall'utente come codice XML non tipizzato nel client.

È inoltre possibile passare i tipi CLR definiti dall'utente come parametri a una query con parametri, utilizzando la stessa procedura illustrata per il tipo di dati xml. Per passare il tipo CLR definito dall'utente dal client nella forma con serializzazione XML, è necessario utilizzare il tipo myEndpoint**::xml**.

In una query con parametri che coinvolge tipi CLR definiti dall'utente, vengono impostati valori diversi nella struttura System.Data.SqlClient.SqlParameter. Ad esempio, per i tipi CLR definiti dall'utente vengono utilizzate le impostazioni delle proprietà seguenti:

  • La proprietà SqlDbType deve essere impostata sul valore Udt.

  • La proprietà ClrTypeName deve essere impostata sul nome completo in tre parti di SQL Server (MyDatabase**.MySchema.**MyUdtType) relativo al tipo definito dall'utente installato, nella forma in cui è stato registrato nell'istanza di SQL Server.