Partager via


Récupérer des données de type défini par l’utilisateur (UDT) dans ADO.NET

S'applique à :SQL Server

Pour créer un type défini par l’utilisateur (UDT) sur le client, l’assembly inscrit en tant qu’UDT dans une base de données SQL Server doit être disponible pour l’application cliente. L'assembly de type défini par l'utilisateur (UDT) peut être placé dans le même répertoire que l'application, ou dans le Global Assembly Cache (GAC). Vous pouvez également définir une référence à l'assembly dans votre projet.

Conditions requises pour l’utilisation des UDT dans ADO.NET

L’assembly chargé dans SQL Server et l’assembly sur le client doivent être compatibles avec l’UDT à créer sur le client. Pour les UDT définis avec le format de sérialisation Native, les assemblys doivent être structurellement compatibles. Pour les assemblys définis avec le format UserDefined, l’assembly doit être disponible sur le client.

Vous n’avez pas besoin d’une copie de l’assembly UDT sur le client pour récupérer les données brutes d’une colonne UDT dans une table.

Remarque

SqlClient peut ne pas charger un UDT si les versions UDT sont incompatibles ou si d’autres problèmes se produisent. Dans ce cas, utilisez des mécanismes de dépannage réguliers pour déterminer pourquoi l’assembly contenant l’UDT est introuvable par l’application appelante. Pour plus d’informations, consultez Diagnostiquer les erreurs avec les assistants de débogage managé.

Les exemples de code de cet article utilisent Microsoft.Data.SqlClient, qui est disponible en tant que package NuGet. Pour ajouter cette dépendance à votre projet, exécutez la commande suivante :

dotnet add package Microsoft.Data.SqlClient

Accéder aux UDT avec un SqlDataReader

Utilisez un Microsoft.Data.SqlClient.SqlDataReader code client pour récupérer un jeu de résultats qui contient une colonne UDT, qui est exposée en tant qu’instance de l’objet.

Exemple

Cet exemple montre comment utiliser la méthode Main pour créer un objet SqlDataReader. Les actions suivantes se produisent dans l'exemple de code :

  1. La méthode Main crée un objet SqlDataReader et récupère les valeurs de la table Points, qui a une colonne UDT nommée Point.

  2. L’UDT Point expose les coordonnées X et Y définies en tant qu’entiers.

  3. L’UDT définit une méthode Distance et une méthode GetDistanceFromXY.

  4. L’exemple de code récupère les valeurs de la clé primaire et des colonnes UDT pour illustrer les fonctionnalités de l’UDT.

  5. L’exemple de code appelle les méthodes Point.Distance et Point.GetDistanceFromXY.

  6. Les résultats s’affichent dans la fenêtre de console.

Remarque

L'application doit déjà avoir une référence à l'assembly UDT.

  • C#
  • Visual Basic .NET
using System;
using Microsoft.Data.SqlClient;

namespace Microsoft.Samples.SqlServer
{
    class ReadPoints
    {
        static void Main()
        {
            string connectionString = GetConnectionString();
            using (SqlConnection cnn = new SqlConnection(connectionString))
            {
                cnn.Open();
                SqlCommand cmd = new SqlCommand(
                    "SELECT ID, Pnt FROM dbo.Points", cnn);
                SqlDataReader rdr = cmd.ExecuteReader();

                while (rdr.Read())
                {
                    // Retrieve the value of the Primary Key column
                    int id = rdr.GetInt32(0);

                    // Retrieve the value of the UDT
                    Point pnt = (Point)rdr[1];

                    // You can also use GetSqlValue and GetValue
                    // Point pnt = (Point)rdr.GetSqlValue(1);
                    // Point pnt = (Point)rdr.GetValue(1);

                    Console.WriteLine(
                        "ID={0} Point={1} X={2} Y={3} DistanceFromXY={4} Distance={5}",
                        id, pnt, pnt.X, pnt.Y, pnt.DistanceFromXY(1, 9), pnt.Distance());
                }
                rdr.Close();
                Console.WriteLine("done");
            }
            static private string GetConnectionString()
            {
                // To avoid storing the connection string in your code,
                // you can retrieve it from a configuration file.
                return "Data Source=(local);Initial Catalog=AdventureWorks2022"
                       + "Integrated Security=SSPI";
            }
        }
    }
}

Lier des UDT en tant qu’octets

Dans certains cas, vous souhaiterez peut-être récupérer les données brutes de la colonne UDT. Le type n’est peut-être pas disponible localement ou vous ne souhaitez pas instancier une instance de l’UDT. Vous pouvez lire les octets bruts dans un tableau d’octets à l’aide de la GetBytes méthode d’un SqlDataReader. Cette méthode lit un flux d'octets à partir de l'offset de colonne spécifié dans la mémoire tampon d'un tableau commençant à un offset de mémoire tampon donné. Une autre option consiste à utiliser l’une des méthodes GetSqlBytes ou GetSqlBinary et à lire tout le contenu dans une seule opération. Dans les deux cas, l’objet UDT n’est jamais instancié. Vous n’avez donc pas besoin de définir une référence à l’UDT dans l’assembly client.

Exemple

Cet exemple montre comment récupérer les Point données sous forme d’octets bruts dans un tableau d’octets à l’aide d’un SqlDataReader. Le code utilise un System.Text.StringBuilder pour convertir les octets bruts en représentation sous forme de chaîne à afficher dans la fenêtre de console.

  • C#
  • Visual Basic .NET
using System;
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;

class GetRawBytes
{
    static void Main()
    {
        string connectionString = GetConnectionString();
        using (SqlConnection cnn = new SqlConnection(connectionString))
        {
            cnn.Open();
            SqlCommand cmd = new SqlCommand("SELECT ID, Pnt FROM dbo.Points", cnn);
            SqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                // Retrieve the value of the Primary Key column
                int id = rdr.GetInt32(0);

                // Retrieve the raw bytes into a byte array
                byte[] buffer = new byte[32];
                long byteCount = rdr.GetBytes(1, 0, buffer, 0, 32);

                // Format and print bytes
                StringBuilder str = new StringBuilder();
                str.AppendFormat("ID={0} Point=", id);

                for (int i = 0; i < byteCount; i++)
                    str.AppendFormat("{0:x}", buffer[i]);
                Console.WriteLine(str.ToString());
            }
            rdr.Close();
            Console.WriteLine("done");
        }
    static private string GetConnectionString()
    {
        // To avoid storing the connection string in your code,
        // you can retrieve it from a configuration file.
        return "Data Source=(local);Initial Catalog=AdventureWorks2022"
            + "Integrated Security=SSPI";
    }
  }
}

Exemple utilisant GetSqlBytes

Cet exemple montre comment récupérer les Point données sous forme d’octets bruts dans une seule opération à l’aide de la GetSqlBytes méthode. Le code utilise un StringBuilder pour convertir les octets bruts en représentation sous forme de chaîne à afficher dans la fenêtre de console.

  • C#
  • Visual Basic .NET
using System;
using Microsoft.Data.SqlClient;
using System.Data.SqlTypes;
using System.Text;

class GetRawBytes
{
    static void Main()
    {
         string connectionString = GetConnectionString();
        using (SqlConnection cnn = new SqlConnection(connectionString))
        {
            cnn.Open();
            SqlCommand cmd = new SqlCommand(
                "SELECT ID, Pnt FROM dbo.Points", cnn);
            SqlDataReader rdr = cmd.ExecuteReader();

            while (rdr.Read())
            {
                // Retrieve the value of the Primary Key column
                int id = rdr.GetInt32(0);

                // Use SqlBytes to retrieve raw bytes
                SqlBytes sb = rdr.GetSqlBytes(1);
                long byteCount = sb.Length;

                // Format and print bytes
                StringBuilder str = new StringBuilder();
                str.AppendFormat("ID={0} Point=", id);

                for (int i = 0; i < byteCount; i++)
                    str.AppendFormat("{0:x}", sb[i]);
                Console.WriteLine(str.ToString());
            }
            rdr.Close();
            Console.WriteLine("done");
        }
    static private string GetConnectionString()
    {
        // To avoid storing the connection string in your code,
        // you can retrieve it from a configuration file.
        return "Data Source=(local);Initial Catalog=AdventureWorks2022"
            + "Integrated Security=SSPI";
    }
  }
}

Utiliser des paramètres UDT

Vous pouvez utiliser des UDT comme paramètres d’entrée et de sortie dans votre code ADO.NET.

Utiliser des UDT dans les paramètres de requête

Vous pouvez utiliser des UDT comme valeurs de paramètre lorsque vous configurez un SqlParameterMicrosoft.Data.SqlClient.SqlCommand objet. L’énumération SqlDbType.Udt d’un SqlParameter objet indique que le paramètre est un UDT lors de l’appel de la Add méthode à la Parameters collection. La UdtTypeName propriété d’un SqlCommand objet spécifie le nom complet de l’UDT dans la base de données à l’aide de la <database>.<schema_name>.<object_name> syntaxe. Utilisez le nom complet pour éviter toute ambiguïté dans votre code.

Une copie locale de l'assembly UDT doit être accessible par le projet client.

Exemple

Le code de cet exemple crée des objets SqlCommand et SqlParameter pour insérer des données dans une colonne UDT dans une table. Le code utilise l’énumération SqlDbType.Udt pour spécifier le type de données et la propriété UdtTypeName de l’objet SqlParameter pour spécifier le nom complet de l’UDT dans la base de données.

  • C#
  • Visual Basic .NET
using System;
using System.Data;
using Microsoft.Data.SqlClient;

class Class1
{
static void Main()
{
  string ConnectionString = GetConnectionString();
     using (SqlConnection cnn = new SqlConnection(ConnectionString))
     {
       SqlCommand cmd = cnn.CreateCommand();
       cmd.CommandText =
         "INSERT INTO dbo.Points (Pnt) VALUES (@Point)";
       cmd.CommandType = CommandType.Text;

       SqlParameter param = new SqlParameter("@Point", SqlDbType.Udt);       param.UdtTypeName = "TestPoint.dbo.Point";       param.Direction = ParameterDirection.Input;       param.Value = new Point(5, 6);       cmd.Parameters.Add(param);

       cnn.Open();
       cmd.ExecuteNonQuery();
       Console.WriteLine("done");
     }
    static private string GetConnectionString()
    {
        // To avoid storing the connection string in your code,
        // you can retrieve it from a configuration file.
        return "Data Source=(local);Initial Catalog=AdventureWorks2022"
            + "Integrated Security=SSPI";
    }
  }
}