Получение данных определяемого пользователем типа (UDT) в ADO.NET
Область применения:SQL Server
Чтобы создать определяемый пользователем тип (UDT) на клиенте, сборка, зарегистрированная в качестве определяемого пользователем в базе данных SQL Server, должна быть доступна клиентскому приложению. Сборку определяемого пользователем типа можно разместить в одном каталоге с приложением или в глобальном кэше сборок. Также можно задать ссылку на сборку в проекте.
Требования к использованию определяемых пользователем пользователей в ADO.NET
Сборка, загруженная в SQL Server, и сборка на клиенте должна быть совместима, чтобы UDT был создан на клиенте. Для определяемых пользователем определяемых пользователем типов с форматом сериализации Native
сборки должны быть структурированы. Для сборок, определенных в формате UserDefined
, сборка должна быть доступна на клиенте.
Для получения необработанных данных из столбца UDT в таблице не требуется копия сборки UDT на клиенте.
Примечание.
SqlClient
может не загрузить UDT в случае несоответствия версий UDT или других проблем. В этом случае используйте обычные механизмы устранения неполадок, чтобы определить, почему сборка, содержащая определяемый пользователем объект, не может быть найдена вызывающим приложением. Дополнительные сведения см. в диагностики ошибок с помощью помощников по управляемой отладке.
Доступ к определяемым пользователем типам пользователей с помощью SqlDataReader
System.Data.SqlClient.SqlDataReader
можно использовать из клиентского кода для получения результирующий набор, содержащий столбец UDT, который предоставляется в качестве экземпляра объекта.
Пример
В этом примере показано, как использовать метод Main
для создания нового объекта SqlDataReader
. В этом примере кода выполняются следующие действия.
Метод Main создает новый объект
SqlDataReader
и извлекает значения из таблицы Point, которая содержит столбец UDT с именем Point.Point
UDT предоставляет координаты X и Y, определенные как целые числа.UDT определяет метод
Distance
и методGetDistanceFromXY
.Образец кода получает значения первичного ключа и столбцов определяемого пользователем типа, чтобы продемонстрировать его возможности.
Пример кода вызывает методы
Point.Distance
иPoint.GetDistanceFromXY
.Результаты выводятся в окне консоли.
Примечание.
Приложение должно содержать ссылку на сборку определяемого пользователем типа.
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";
}
}
}
}
Привязка определяемых пользователем пользователей в виде байтов
В некоторых ситуациях может потребоваться получить необработанные данные из столбца UDT. Возможно, тип недоступен локально или вы не хотите создать экземпляр определяемого пользователем типа. Необработанные байты можно считывать в массив байтов с помощью метода GetBytes
SqlDataReader
. Этот метод считывает поток байт с указанного смещения столбца в буфер в виде массива, начиная с указанного смещения. Другим вариантом является использование одного из методов GetSqlBytes
или GetSqlBinary
и чтение всего содержимого в одной операции. В любом случае объект UDT никогда не создается, поэтому не нужно задавать ссылку на определяемый пользователем объект в клиентской сборке.
Пример
В этом примере показано, как получить данные Point
в виде необработанных байтов в массив байтов с помощью SqlDataReader
. Код использует System.Text.StringBuilder
для преобразования необработанных байтов в строковое представление, которое будет отображаться в окне консоли.
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";
}
}
}
Пример использования GetSqlBytes
В этом примере показано, как получить данные Point
в виде необработанных байтов в одной операции с помощью метода GetSqlBytes
. Код использует StringBuilder
для преобразования необработанных байтов в строковое представление, которое будет отображаться в окне консоли.
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";
}
}
}
Работа с параметрами определяемого пользователем типа
Определяемые пользователем типы используются в коде ADO.NET как в качестве входных, так и в качестве выходных параметров.
Использование определяемых пользователем типов в параметрах запроса
Определяемые пользователем объекты можно использовать в качестве значений параметров при настройке SqlParameter
для объекта System.Data.SqlClient.SqlCommand
. Перечисление SqlDbType.Udt
объекта SqlParameter
используется для указания того, что параметр является определяемой пользователем функцией при вызове метода Add
в коллекцию Parameters
. Свойство UdtTypeName
объекта SqlCommand
используется для указания полного имени определяемого пользователя в базе данных с помощью синтаксиса <database>.<schema_name>.<object_name>
. Необходимо использовать полное имя, чтобы избежать неоднозначности в коде.
Локальная копия сборки определяемого пользователем типа должна быть доступна в проекте клиента.
Пример
В этом примере код создает объекты SqlCommand
и SqlParameter
для вставки данных в столбец UDT в таблице. Код использует перечисление SqlDbType.Udt
для указания типа данных и свойства UdtTypeName
объекта SqlParameter
, чтобы указать полное имя определяемого пользователем типа в базе данных.
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";
}
}
}