Recuperar dados de tipo definido pelo usuário (UDT) no ADO.NET
Aplica-se:SQL Server
Para criar um UDT (tipo definido pelo usuário) no cliente, o assembly que foi registrado como um UDT em um banco de dados SQL Server deve estar disponível para o aplicativo cliente. O assembly UDT pode ser colocado no mesmo diretório que o aplicativo ou no Cache de Assembly Global (GAC). Também é possível definir uma referência para o assembly em seu projeto.
Requisitos para usar UDTs no ADO.NET
O assembly carregado no SQL Server e o assembly no cliente devem ser compatíveis para que o UDT seja criado no cliente. Para UDTs definidos com o formato de serialização Native
, os assemblies devem ser estruturalmente compatíveis. Para assemblies definidos com o formato UserDefined
, o assembly deve estar disponível no cliente.
Você não precisa de uma cópia do assembly UDT no cliente para recuperar os dados brutos de uma coluna UDT em uma tabela.
Observação
SqlClient
pode falhar ao carregar um UDT no caso de versões de UDT incompatíveis ou outros problemas. Nesse caso, use mecanismos regulares de solução de problemas para determinar por que o assembly que contém a UDT não pode ser encontrado pelo aplicativo de chamada. Para obter mais informações, consulte Diagnosticar erros com assistentes de depuração gerenciados.
Acessar UDTs com um SqlDataReader
Um System.Data.SqlClient.SqlDataReader
pode ser usado do código do cliente para recuperar um conjunto de resultados que contém uma coluna UDT, que é exposta como uma instância do objeto.
Exemplo
Este exemplo mostra como usar o método Main
para criar um novo objeto SqlDataReader
. As ações a seguir ocorrem no exemplo de código:
O método Main cria um novo objeto
SqlDataReader
e recupera os valores da tabela Points, que tem uma coluna UDT chamada Point.O
Point
UDT expõe coordenadas X e Y definidas como inteiros.A UDT define um método
Distance
e um métodoGetDistanceFromXY
.O código de exemplo recupera os valores da chave primária e das colunas UDT para demonstrar os recursos do UDT.
O código de exemplo chama os métodos
Point.Distance
ePoint.GetDistanceFromXY
.Os resultados são exibidos na janela do console.
Observação
O aplicativo já deve ter uma referência para o assembly 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";
}
}
}
}
Associar UDTs como bytes
Em algumas situações, talvez você queira recuperar os dados brutos da coluna UDT. Talvez o tipo não esteja disponível localmente ou você não queira instanciar uma instância do UDT. Você pode ler os bytes brutos em uma matriz de bytes usando o método GetBytes
de um SqlDataReader
. Esse método lê um fluxo de bytes do deslocamento de coluna especificado no buffer de uma matriz, começando com um deslocamento de buffer especificado. Outra opção é usar um dos métodos GetSqlBytes
ou GetSqlBinary
e ler todo o conteúdo em uma única operação. Em ambos os casos, o objeto UDT nunca é instanciado, portanto, você não precisa definir uma referência ao UDT no assembly do cliente.
Exemplo
Este exemplo mostra como recuperar os dados Point
como bytes brutos em uma matriz de bytes usando um SqlDataReader
. O código usa um System.Text.StringBuilder
para converter os bytes brutos em uma representação de cadeia de caracteres a ser exibida na janela do console.
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";
}
}
}
Exemplo usando GetSqlBytes
Este exemplo mostra como recuperar os dados Point
como bytes brutos em uma única operação usando o método GetSqlBytes
. O código usa um StringBuilder
para converter os bytes brutos em uma representação de cadeia de caracteres a ser exibida na janela do console.
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";
}
}
}
Trabalhar com parâmetros UDT
Os UDTs podem ser usados como parâmetros de entrada e de saída no código do ADO.NET.
Usar UDTs em parâmetros de consulta
UDTs podem ser usados como valores de parâmetro ao configurar um SqlParameter
para um objeto System.Data.SqlClient.SqlCommand
. A enumeração SqlDbType.Udt
de um objeto SqlParameter
é usada para indicar que o parâmetro é um UDT ao chamar o método Add
para a coleção Parameters
. A propriedade UdtTypeName
de um objeto SqlCommand
é usada para especificar o nome totalmente qualificado do UDT no banco de dados usando a sintaxe <database>.<schema_name>.<object_name>
. Você deve usar o nome totalmente qualificado para evitar ambiguidade em seu código.
Uma cópia local do assembly UDT deve estar disponível para o projeto cliente.
Exemplo
O código neste exemplo cria objetos SqlCommand
e SqlParameter
para inserir dados em uma coluna UDT em uma tabela. O código usa a enumeração SqlDbType.Udt
para especificar o tipo de dados e a propriedade UdtTypeName
do objeto SqlParameter
para especificar o nome totalmente qualificado da UDT no banco de dados.
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";
}
}
}
Conteúdo relacionado
- tipos definidos pelo usuário do Access no ADO.NET