Mengambil data jenis yang ditentukan pengguna (UDT) di ADO.NET

Berlaku untuk:SQL Server

Untuk membuat jenis yang ditentukan pengguna (UDT) pada klien, rakitan yang terdaftar sebagai UDT dalam database SQL Server harus tersedia untuk aplikasi klien. Rakitan UDT dapat ditempatkan di direktori yang sama dengan aplikasi, atau di Global Assembly Cache (GAC). Anda juga dapat mengatur referensi ke rakitan dalam proyek Anda.

Persyaratan untuk menggunakan UDT di ADO.NET

Rakitan yang dimuat di SQL Server dan rakitan pada klien harus kompatibel agar UDT dibuat pada klien. Untuk UDT yang ditentukan dengan format serialisasi Native, rakitan harus kompatibel secara struktural. Untuk rakitan yang ditentukan dengan format UserDefined, rakitan harus tersedia pada klien.

Anda tidak memerlukan salinan rakitan UDT pada klien untuk mengambil data mentah dari kolom UDT dalam tabel.

Catatan

SqlClient mungkin gagal memuat UDT jika versi UDT tidak cocok atau masalah lain terjadi. Dalam hal ini, gunakan mekanisme pemecahan masalah reguler untuk menentukan mengapa rakitan yang berisi UDT tidak dapat ditemukan oleh aplikasi panggilan. Untuk informasi selengkapnya, lihat Mendiagnosis Kesalahan dengan Asisten Penelusuran Kesalahan Terkelola.

Contoh kode dalam artikel ini menggunakan Microsoft.Data.SqlClient, yang tersedia sebagai paket NuGet. Untuk menambahkan dependensi ini ke proyek Anda, jalankan perintah berikut:

dotnet add package Microsoft.Data.SqlClient

Mengakses UDT dengan SqlDataReader

Microsoft.Data.SqlClient.SqlDataReader Gunakan dari kode klien untuk mengambil kumpulan hasil yang berisi kolom UDT, yang diekspos sebagai instans objek.

Contoh

Contoh ini menunjukkan cara menggunakan metode Main untuk membuat objek SqlDataReader baru. Tindakan berikut terjadi dalam contoh kode:

  1. Metode Utama membuat objek SqlDataReader baru dan mengambil nilai dari tabel Points, yang memiliki kolom UDT bernama Point.

  2. UDT Point mengekspos koordinat X dan Y yang didefinisikan sebagai bilangan bulat.

  3. UDT mendefinisikan metode Distance dan metode GetDistanceFromXY.

  4. Kode sampel mengambil nilai kunci primer dan kolom UDT untuk menunjukkan kemampuan UDT.

  5. Kode sampel memanggil metode Point.Distance dan Point.GetDistanceFromXY.

  6. Hasilnya ditampilkan di jendela konsol.

Catatan

Aplikasi harus sudah memiliki referensi ke rakitan UDT.

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";
            }
        }
    }
}

Ikat UDT sebagai byte

Dalam beberapa situasi, Anda mungkin ingin mengambil data mentah dari kolom UDT. Mungkin jenisnya tidak tersedia secara lokal, atau Anda tidak ingin membuat instans UDT. Anda dapat membaca byte mentah ke dalam array byte dengan menggunakan GetBytes metode SqlDataReader. Metode ini membaca aliran byte dari offset kolom yang ditentukan ke dalam buffer array yang dimulai pada offset buffer tertentu. Opsi lain adalah menggunakan salah satu metode GetSqlBytes atau GetSqlBinary dan membaca semua konten dalam satu operasi. Dalam kedua kasus, objek UDT tidak pernah dibuat, jadi Anda tidak perlu mengatur referensi ke UDT di perakitan klien.

Contoh

Contoh ini menunjukkan cara mengambil Point data sebagai byte mentah ke dalam array byte dengan menggunakan SqlDataReader. Kode menggunakan System.Text.StringBuilder untuk mengonversi byte mentah menjadi representasi string yang akan ditampilkan di jendela konsol.

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";
    }
  }
}

Contoh menggunakan GetSqlBytes

Contoh ini menunjukkan cara mengambil Point data sebagai byte mentah dalam satu operasi dengan menggunakan GetSqlBytes metode . Kode menggunakan StringBuilder untuk mengonversi byte mentah menjadi representasi string yang akan ditampilkan di jendela konsol.

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";
    }
  }
}

Bekerja dengan parameter UDT

Anda dapat menggunakan UDT sebagai parameter input dan output dalam kode ADO.NET Anda.

Menggunakan UDT dalam parameter kueri

Anda dapat menggunakan UDT sebagai nilai parameter saat menyiapkan SqlParameter untuk Microsoft.Data.SqlClient.SqlCommand objek. Enumerasi SqlDbType.UdtSqlParameter objek menunjukkan bahwa parameter adalah UDT saat memanggil Add metode ke Parameters koleksi. Properti UdtTypeNameSqlCommand objek menentukan nama UDT yang sepenuhnya memenuhi syarat dalam database dengan menggunakan <database>.<schema_name>.<object_name> sintaks. Gunakan nama yang sepenuhnya memenuhi syarat untuk menghindari ambiguitas dalam kode Anda.

Salinan lokal rakitan UDT harus tersedia untuk proyek klien.

Contoh

Kode dalam contoh ini membuat objek SqlCommand dan SqlParameter untuk menyisipkan data ke dalam kolom UDT dalam tabel. Kode menggunakan enumerasi SqlDbType.Udt untuk menentukan jenis data, dan properti UdtTypeName objek SqlParameter untuk menentukan nama UDT yang sepenuhnya memenuhi syarat dalam database.

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";
    }
  }
}