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:
El método Main crea un nuevo objeto
SqlDataReader
y recupera los valores de la tabla Points, que tiene una columna UDT denominada Point.El
Point
UDT expone coordenadas X e Y definidas como enteros.El UDT define un método
Distance
y un métodoGetDistanceFromXY
.El código muestra recupera los valores de las columnas de UDT y de clave principal para mostrar las capacidades del UDT.
El código de ejemplo llama a los métodos
Point.Distance
yPoint.GetDistanceFromXY
.Los resultados se muestran en la ventana de la consola.
Nota:
La aplicación ya debe tener una referencia al ensamblado UDT.
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.
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.
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.
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";
}
}
}