適用於:SQL Server
若要在用戶端建立使用者定義型別(UDT),必須在 SQL Server 資料庫中註冊為 UDT 的組合語言可供用戶端應用程式使用。 UDT 元件可以放在與應用程式相同的目錄中,或放在全域程式集緩存 (GAC) 中。 您也可以設定專案中元件的參考。
在 ADO.NET 中使用UDT的需求
SQL Server 載入的組合語言與用戶端的組合語言必須相容,才能在用戶端建立 UDT。 對於以 Native 串行化格式定義的 UDT,元件在結構上必須相容。 對於以 UserDefined 格式定義的元件,必須在用戶端上使用元件。
你不需要在客戶端取得 UDT 組件的副本,就能從表格中的 UDT 欄位取得原始資料。
注意
SqlClient 若 UDT 版本不匹配或其他問題,可能會無法載入 UDT。 在此情況下,請使用一般疑難解答機制來判斷呼叫應用程式找不到包含UDT的元件的原因。 如需詳細資訊,請參閱 使用 Managed 偵錯小幫手診斷錯誤。
本文的程式碼範例使用 Microsoft.Data.SqlClient,該套件可作為 NuGet 套件取得。 要將此依賴性加入專案,請執行以下指令:
dotnet add package Microsoft.Data.SqlClient
使用 SqlDataReader 存取 UDT
使用 Microsoft.Data.SqlClient.SqlDataReader 客戶端的程式碼取得包含 UDT 欄位的結果集,該欄位作為物件的實例被公開。
範例
這個範例示範如何使用 Main 方法來建立新的 SqlDataReader 物件。 下列動作會發生在程式代碼範例中:
Main 方法會建立新的
SqlDataReader物件,並從 Points 數據表擷取值,其具有名為 Point 的 UDT 數據行。PointUDT 會公開定義為整數的 X 和 Y 座標。UDT 會定義
Distance方法和GetDistanceFromXY方法。範例程式碼會取得主鍵與 UDT 欄位的值,以展示 UDT 的功能。
範例程式代碼會呼叫
Point.Distance和Point.GetDistanceFromXY方法。結果會顯示在主控台視窗中。
注意
應用程式必須已經有 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";
}
}
}
}
將 UDT 系結為位元組
在某些情況下,您可能想要從 UDT 資料行擷取原始數據。 也許該型別在本地無法取得,或者你不想實例化 UDT。 你可以用 GetBytesSqlDataReader的方法將原始位元組讀入位元組陣列。 這個方法會從指定的數據行位移讀取位元組數據流,以從指定的緩衝區位移開始陣列的緩衝區。 另一個選項是使用其中一個 GetSqlBytes 或 GetSqlBinary 方法,並在單一作業中讀取所有內容。 不論是哪一種情況,都永遠不會具現化 UDT 物件,因此您不需要在用戶端元件中設定 UDT 的參考。
範例
此範例展示了如何 Point 利用 SqlDataReader。 程式代碼會使用 System.Text.StringBuilder,將原始位元組轉換成要顯示在主控台視窗中的字串表示。
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";
}
}
}
使用 GetSqlBytes 的範例
此範例展示了如何利用該GetSqlBytes方法在單一操作中取得Point原始位元組資料。 程式代碼會使用 StringBuilder,將原始位元組轉換成要顯示在主控台視窗中的字串表示。
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";
}
}
}
使用UDT參數
你可以在 ADO.NET 程式碼中同時使用UDT作為輸入和輸出參數。
在查詢參數中使用UDT
你可以在為物件設定 a SqlParameterMicrosoft.Data.SqlClient.SqlCommand 時,使用 UDT 作為參數值。
SqlDbType.Udt物件的列舉SqlParameter表示該參數在呼叫Add該方法到Parameters集合時為 UDT。
UdtTypeName物件的SqlCommand屬性透過語<database>.<schema_name>.<object_name>法指定資料庫中 UDT 的完全限定名稱。 使用完全限定的名稱以避免程式碼中的歧義。
用戶端項目必須使用UDT元件的本機複本。
範例
此範例中的程式代碼會建立 SqlCommand 和 SqlParameter 物件,以將數據插入數據表中的 UDT 資料行。 程序代碼會使用 SqlDbType.Udt 列舉來指定數據類型,以及 UdtTypeName 物件的 SqlParameter 屬性,以指定資料庫中 UDT 的完整名稱。
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";
}
}
}
相關內容
- 在 ADO.NET 中存取使用者定義型別