Compartir a través de


Recuperación de datos de tipo definido por el usuario (UDT) en ADO.NET

Se aplica a:SQL Server

Para crear un tipo definido por el usuario (UDT) en el cliente, el ensamblado que se registró como UDT en una base de datos de SQL Server debe estar disponible para la aplicación cliente. El ensamblado UDT se puede colocar en el mismo directorio que la aplicación o en la caché de ensamblados global (GAC). También puede establecer una referencia al ensamblado en su proyecto.

Requisitos para usar udT en ADO.NET

El ensamblado cargado en SQL Server y el ensamblado en el cliente deben ser compatibles para que el UDT se cree en el cliente. Para los UDT definidos con el formato de serialización Native, los ensamblados deben ser estructuralmente compatibles. Para los ensamblados definidos con el formato UserDefined, el ensamblado debe estar disponible en el cliente.

No necesita una copia del ensamblado UDT en el cliente para recuperar los datos sin procesar de una columna UDT en una tabla.

Nota:

SqlClient podría no cargar un UDT en caso de que no coincidan las versiones udT u otros problemas. En este caso, use mecanismos de solución de problemas normales para determinar por qué el ensamblado que contiene el UDT no se puede encontrar mediante la aplicación que realiza la llamada. Para obtener más información, consulte Diagnosticar errores con asistentes de depuración administrada.

Acceso a udT con sqlDataReader

Un System.Data.SqlClient.SqlDataReader se puede usar desde el código de cliente para recuperar un conjunto de resultados que contiene una columna UDT, que se expone como una instancia del objeto.

Ejemplo

En este ejemplo se muestra cómo usar el método Main para crear un nuevo objeto SqlDataReader. En el ejemplo de código se producen las siguientes acciones:

  1. El método Main crea un nuevo objeto SqlDataReader y recupera los valores de la tabla Points, que tiene una columna UDT denominada Point.

  2. El Point UDT expone coordenadas X e Y definidas como enteros.

  3. El UDT define un método Distance y un método GetDistanceFromXY.

  4. El código muestra recupera los valores de las columnas de UDT y de clave principal para mostrar las capacidades del UDT.

  5. El código de ejemplo llama a los métodos Point.Distance y Point.GetDistanceFromXY.

  6. Los resultados se muestran en la ventana de la consola.

Nota:

La aplicación ya debe tener una referencia al ensamblado UDT.

  • de C#
  • de Visual Basic para .NET
using System;
using System.Data.Sql;
using System.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";
            }
        }
    }
}

Enlazar UDT como bytes

En algunas situaciones, es posible que desee recuperar los datos sin procesar de la columna UDT. Quizás el tipo no esté disponible localmente o no quiera crear instancias de una instancia del UDT. Puede leer los bytes sin procesar en una matriz de bytes mediante el método GetBytes de un SqlDataReader. Este método lee un flujo de bytes a partir del desplazamiento de la columna especificada en el búfer de una matriz, comenzando en el desplazamiento del búfer especificado. Otra opción es usar uno de los métodos GetSqlBytes o GetSqlBinary y leer todo el contenido en una sola operación. En cualquier caso, nunca se crea una instancia del objeto UDT, por lo que no es necesario establecer una referencia al UDT en el ensamblado de cliente.

Ejemplo

En este ejemplo se muestra cómo recuperar los datos de Point como bytes sin procesar en una matriz de bytes mediante un SqlDataReader. El código usa un System.Text.StringBuilder para convertir los bytes sin procesar en una representación de cadena que se mostrará en la ventana de la consola.

  • de C#
  • de Visual Basic para .NET
using System;
using System.Data.Sql;
using System.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";
    }
  }
}

Ejemplo de uso de GetSqlBytes

En este ejemplo se muestra cómo recuperar los datos de Point como bytes sin procesar en una sola operación mediante el método GetSqlBytes. El código usa un StringBuilder para convertir los bytes sin procesar en una representación de cadena que se mostrará en la ventana de la consola.

  • de C#
  • de Visual Basic para .NET
using System;
using System.Data.Sql;
using System.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";
    }
  }
}

Trabajar con parámetros UDT

Los UDT se pueden utilizar en el código de ADO.NET como parámetros de entrada y de salida.

Uso de UDT en parámetros de consulta

Los UDT se pueden usar como valores de parámetro al configurar un SqlParameter para un objeto System.Data.SqlClient.SqlCommand. La enumeración SqlDbType.Udt de un objeto SqlParameter se usa para indicar que el parámetro es un UDT al llamar al método Add a la colección Parameters. La propiedad UdtTypeName de un objeto SqlCommand se usa para especificar el nombre completo del UDT en la base de datos mediante la sintaxis <database>.<schema_name>.<object_name>. Debe usar el nombre completo para evitar ambigüedad en el código.

Debe haber una copia local del ensamblado UDT disponible para el proyecto del cliente.

Ejemplo

El código de este ejemplo crea SqlCommand y SqlParameter objetos para insertar datos en una columna UDT de una tabla. El código usa la enumeración SqlDbType.Udt para especificar el tipo de datos y la propiedad UdtTypeName del objeto SqlParameter para especificar el nombre completo del UDT en la base de datos.

  • de C#
  • de Visual Basic para .NET
using System;
using System.Data;
using System.Data.Sql;
using System.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";
    }
  }
}