SQL-CLR 型別對應 (LINQ to SQL)
在 LINQ to SQL 中,關聯式資料庫的資料模型會對應至以您選擇之程式語言表示的物件模型 (Object Model)。 執行應用程式時,LINQ to SQL 會將物件模型中的 Language Integrated Query (LINQ) 轉譯成 SQL,並將這些查詢傳送至資料庫進行執行。 當資料庫傳回結果時,LINQ to SQL 會將結果轉譯回您可以在自己的程式語言中處理的物件。
若要在物件模型與資料庫之間轉譯資料,您必須定義「型別對應」(Type Mapping)。 LINQ to SQL 會使用型別對應來比對每個 Common Language Runtime (CLR) 型別與特定 SQL Server 型別。 您可以使用以屬性 (Attribute) 為基礎的對應,在物件模型內部定義型別對應和其他對應資訊,例如資料庫結構與資料表關聯性 (Relationship)。 此外,您也可以使用外部對應檔案,在物件模型外部指定對應資訊。 如需詳細資訊,請參閱以屬性為基礎的對應 (LINQ to SQL) 和外部對應參考 (LINQ to SQL)。
這個主題將討論下列重點:
預設型別對應
型別對應的執行階段行為對照表
CLR 與 SQL 執行之間的行為差異
Enum 對應
數字對應
文字和 XML 對應
日期和時間對應
二進位對應
其他對應
預設型別對應
您可以使用物件關聯式設計工具 (O/R 設計工具) 或 SQLMetal 命令列工具,自動建立物件模型或外部對應檔案。 這些工具的預設型別對應會定義選擇哪些 CLR 型別來對應至 SQL Server 資料庫內部的資料行。 如需使用這些工具的詳細資訊,請參閱建立物件模型 (LINQ to SQL)。
您也可以根據物件模型或外部對應檔案中的對應資訊,使用 CreateDatabase 方法來建立 SQL Server 資料庫。 CreateDatabase 方法的預設型別對應會定義建立哪些 SQL Server 資料行型別來對應至物件模型中的 CLR 型別。 如需詳細資訊,請參閱 HOW TO:動態建立資料庫 (LINQ to SQL)。
型別對應的執行階段行為對照表
下圖顯示從資料庫中擷取資料或將資料儲存至資料庫時,特定型別對應的預期執行階段行為。 除了序列化 (Serialization) 以外,LINQ to SQL 不支援此對照表中未指定之任何 CLR 或 SQL Server 資料型別之間的對應。 如需序列化支援的詳細資訊,請參閱二進位序列化。
注意事項 |
---|
在資料庫之間來回轉譯時,某些型別對應可能會造成溢位或資料遺失的例外狀況 (Exception)。 |
自訂型別對應
在 LINQ to SQL 中,您不會受限於 O/R 設計工具、SQLMetal 和 CreateDatabase 方法的預設型別對應。 您可以在 DBML 檔案中明確指定自訂型別對應,藉以建立這些對應。 然後,您就可以使用該 DBML 檔案來建立物件模型程式碼和對應檔案。 如需詳細資訊,請參閱 SQL-CLR 自訂型別對應 (LINQ to SQL)。
CLR 與 SQL 執行之間的行為差異
由於 CLR 與 SQL Server 之間存在精確度和執行差異,所以您可能會收到不同的結果或產生不同的行為,端視執行計算的位置而定。 在 LINQ to SQL 查詢中執行的計算實際上會轉譯成 Transact-SQL,然後在 SQL Server 資料庫上執行。 在 LINQ to SQL 查詢外部執行的計算則會在 CLR 的內容中執行。
例如,下面是 CLR 與 SQL Server 之間的一些行為差異:
SQL Server 排序某些資料型別的方式與 CLR 中對等資料型別的排序方式不同。 例如,SQL Server 資料型別 UNIQUEIDENTIFIER 的排序方式就與 CLR 資料型別 System.Guid 的排序方式不同。
SQL Server 處理某些字串比較作業的方式與 CLR 不同。 在 SQL Server 中,字串比較行為會因伺服器的定序 (Collation) 設定而不同。 如需詳細資訊,請參閱《Microsoft SQL Server 線上叢書》中的使用定序。
SQL Server 與 CLR 可能會針對某些對應函式傳回不同的值。 例如,等號比較函式便有所不同,因為如果兩個字串只有尾端泛空白字元 (White Space) 不同,SQL Server 就會將它們視為相等,而 CLR 則會將它們視為不相等。
Enum 對應
LINQ to SQL 支援以下列兩種方式將 CLR System.Enum 型別對應至 SQL Server 型別:
對應至 SQL 數字型別 (TINYINT、SMALLINT、INT、BIGINT)
當您將 CLR System.Enum 型別對應至 SQL 數字型別 (Numeric Type) 時,就會將 CLR System.Enum 的基礎整數值對應至 SQL Server 資料庫資料行的值。 例如,如果名為 DaysOfWeek 的 System.Enum 包含名為 Tue 而且具有基礎整數值 3 的成員,則該成員就會對應至資料庫值 3。
對應至 SQL 文字型別 (CHAR、NCHAR、VARCHAR、NVARCHAR)
當您將 CLR System.Enum 型別對應至 SQL 文字型別時,SQL 資料庫值會對應至 CLR System.Enum 成員的名稱。 例如,如果名為 DaysOfWeek 的 System.Enum 包含名為 Tue 而且具有基礎整數值 3 的成員,則該成員就會對應至資料庫值 Tue。
注意事項 |
---|
將 SQL 文字型別對應至 CLR System.Enum 時,請單獨在對應的 SQL 資料行中加入 Enum 成員的名稱。Enum 對應的 SQL 資料行不支援其他值。 |
O/R 設計工具和 SQLMetal 命令列工具無法自動將 SQL 型別對應至 CLR Enum 類別 (Class)。 您必須針對供 O/R 設計工具和 SQLMetal 使用自訂 DBML 檔案,藉以明確設定此對應。 如需自訂型別對應的詳細資訊,請參閱 SQL-CLR 自訂型別對應 (LINQ to SQL)。
由於適用於列舉型別 (Enumeration) 的 SQL 資料行與其他數值和文字資料行具有相同的型別,所以這些工具將無法辨識您的意圖,而且它們會預設為對應,如下列「數字對應」和「文字和 XML 對應」章節所述。 如需使用 DBML 檔案來產生程式碼的詳細資訊,請參閱 LINQ to SQL 的程式碼產生。
DataContext.CreateDatabase 方法會建立數字型別的 SQL 資料行來對應 CLR System.Enum 型別。
數字對應
LINQ to SQL 可讓您對應許多 CLR 和 SQL Server 數字型別。 下表顯示根據資料庫建置 (Build) 物件模型或外部對應檔案時,O/R 設計工具和 SQLMetal 所選取的 CLR 型別。
SQL Server 型別 |
O/R 設計工具和 SQLMetal 所使用的預設 CLR 型別對應 |
---|---|
BIT |
|
TINYINT |
|
INT |
|
BIGINT |
|
SMALLMONEY |
|
MONEY |
|
DECIMAL |
|
NUMERIC |
|
REAL/FLOAT(24) |
|
FLOAT/FLOAT(53) |
下表顯示 DataContext.CreateDatabase 方法用於定義建立哪些 SQL 資料行型別來對應至 CLR 型別 (定義於物件模型或外部對應檔案中) 的預設型別對應。
CLR 型別 |
DataContext.CreateDatabase 所使用的預設 SQL Server 型別 |
---|---|
BIT |
|
TINYINT |
|
SMALLINT |
|
INT |
|
BIGINT |
|
SMALLINT |
|
INT |
|
BIGINT |
|
DECIMAL(20) |
|
DECIMAL(29,4) |
|
REAL |
|
FLOAT |
雖然還有許多其他數字對應可供您選擇,但是在資料庫之間來回轉譯時,某些對應可能會造成溢位或資料遺失的例外狀況。 如需詳細資訊,請參閱型別對應的執行階段行為對照表。
Decimal 和 Money 型別
SQL Server DECIMAL 型別的預設精確度 (小數點左右的 18 個十進位數字) 小於預設搭配使用之 CLR Decimal 型別的精確度。 當您將資料儲存至資料庫時,這可能會導致精確度遺失。 不過,如果 SQL Server DECIMAL 型別設定為大於 29 個位數的精確度,可能會發生完全相反的情況。 當 SQL Server DECIMAL 型別已經設定為大於 CLR System.Decimal 的精確度時,如果從資料庫中擷取資料,就可能會發生精確度遺失。
SQL Server MONEY 和 SMALLMONEY 型別 (預設也會與 CLR System.Decimal 型別搭配使用) 具有更小的精確度,而且將資料儲存至資料庫時,可能會造成溢位或資料遺失的例外狀況。
文字和 XML 對應
還有許多以文字為基礎的型別和 XML 型別,可讓您透過 LINQ to SQL 進行對應。 下表顯示根據資料庫建置物件模型或外部對應檔案時,O/R 設計工具和 SQLMetal 所選取的 CLR 型別。
SQL Server 型別 |
O/R 設計工具和 SQLMetal 所使用的預設 CLR 型別對應 |
---|---|
CHAR |
|
NCHAR |
|
VARCHAR |
|
NVARCHAR |
|
TEXT |
|
NTEXT |
|
XML |
下表顯示 DataContext.CreateDatabase 方法用於定義建立哪些 SQL 資料行型別來對應至 CLR 型別 (定義於物件模型或外部對應檔案中) 的預設型別對應。
CLR 型別 |
DataContext.CreateDatabase 所使用的預設 SQL Server 型別 |
---|---|
NCHAR(1) |
|
NVARCHAR(4000) |
|
NVARCHAR(4000) |
|
實作 Parse() 和 ToString() 的自訂型別 |
NVARCHAR(MAX) |
雖然還有許多其他以文字為基礎的對應和 XML 對應可供您選擇,但是在資料庫之間來回轉譯時,某些對應可能會造成溢位或資料遺失的例外狀況。 如需詳細資訊,請參閱型別對應的執行階段行為對照表。
XML 型別
從 Microsoft SQL Server 2005 開始,就提供了 SQL Server XML 資料型別。 您可以將 SQL Server XML 資料類型對應至 XElement、XDocument 或 String。 如果資料行儲存的 XML 片段無法讀入 XElement 中,則該資料行必須對應至 String,以免發生執行階段錯誤。 必須對應至 String 的 XML 片段包括:
XML 項目的序列
屬性
公用識別項 (PI)
註解
雖然您可以將 XElement 和 XDocument 對應至 SQL Server (如型別對應的執行階段行為對照表中所示),但是 DataContext.CreateDatabase 方法沒有這些型別的預設 SQL Server 型別對應。
自訂型別
如果某個類別 (Class) 實作 Parse() 和 ToString(),您就可以將此物件對應至任何 SQL 文字型別 (CHAR、NCHAR、VARCHAR、NVARCHAR、TEXT、NTEXT 或 XML)。 此物件會透過將 ToString() 所傳回的值傳送至對應的資料庫資料行,儲存在資料庫中。 此物件的重建方式是針對資料庫所傳回的字串叫用 (Invoke) Parse()。
注意事項 |
---|
LINQ to SQL 不支援使用 System.Xml.Serialization.IXmlSerializable 進行序列化。 |
日期和時間對應
在 LINQ to SQL 中,您可以對應許多 SQL Server 日期和時間型別。 下表顯示根據資料庫建置物件模型或外部對應檔案時,O/R 設計工具和 SQLMetal 所選取的 CLR 型別。
SQL Server 型別 |
O/R 設計工具和 SQLMetal 所使用的預設 CLR 型別對應 |
---|---|
SMALLDATETIME |
|
DATETIME |
|
DATETIME2 |
|
DATETIMEOFFSET |
|
DATE |
|
TIME |
下表顯示 DataContext.CreateDatabase 方法用於定義建立哪些 SQL 資料行型別來對應至 CLR 型別 (定義於物件模型或外部對應檔案中) 的預設型別對應。
CLR 型別 |
DataContext.CreateDatabase 所使用的預設 SQL Server 型別 |
---|---|
DATETIME |
|
DATETIMEOFFSET |
|
TIME |
雖然還有許多其他日期和時間對應可供您選擇,但是在資料庫之間來回轉譯時,某些對應可能會造成溢位或資料遺失的例外狀況。 如需詳細資訊,請參閱型別對應的執行階段行為對照表。
注意事項 |
---|
從 Microsoft SQL Server 2008 開始,就提供了 SQL Server 型別 DATETIME2、DATETIMEOFFSET、DATE 和 TIME。從 .NET Framework 3.5 版 SP1 開始,LINQ to SQL 支援對應至這些新的型別。 |
System.Datetime
CLR System.DateTime 型別的範圍和精確度大於 SQL Server DATETIME 型別的範圍和精確度,而這是 DataContext.CreateDatabase 方法的預設型別對應。 若要協助避免與超出 DATETIME 範圍之日期相關的例外狀況,請使用 DATETIME2 (從 Microsoft SQL Server 2008 開始提供)。 DATETIME2 可以比對 CLR System.DateTime 的範圍和精確度。
SQL Server 日期沒有 TimeZone 的概念,而這是 CLR 中完全支援的功能。 不論原始 DateTimeKind 資訊為何,TimeZone 值會原樣儲存至資料庫,而不進行 TimeZone 轉換。 從資料庫擷取 DateTime 值時,這個值會原樣載入至 DateTimeKind,並將 Unspecified 設為 DateTime 中。 如需支援之 System.DateTime 方法的詳細資訊,請參閱 System.DateTime 方法 (LINQ to SQL)。
System.TimeSpan
Microsoft SQL Server 2008 和 .NET Framework 3.5 SP1 可讓您將 CLR System.TimeSpan 型別對應至 SQL Server TIME 型別。 不過,CLR System.TimeSpan 所支援的範圍與 SQL Server TIME 型別所支援的範圍之間具有大幅差異。 將小於 0 或大於 23:59:59.9999999 小時的值對應至 SQL TIME 將會造成溢位的例外狀況。 如需詳細資訊,請參閱 System.TimeSpan 方法 (LINQ to SQL)。
在 Microsoft SQL Server 2000 和 SQL Server 2005 中,您無法將資料庫欄位對應至 TimeSpan。 但是,支援 TimeSpan 的作業,因為 TimeSpan 值可以從 DateTime 減法傳回,或引進運算式中做為常值或繫結變數。
二進位對應
可對應至 CLR 型別 System.Data.Linq.Binary 的 SQL Server 型別有許多種。 下表顯示根據資料庫建置物件模型或外部對應檔案時,導致 O/R 設計工具和 SQLMetal 定義 CLR System.Data.Linq.Binary 型別的 SQL Server 型別。
SQL Server 型別 |
O/R 設計工具和 SQLMetal 所使用的預設 CLR 型別對應 |
---|---|
BINARY(50) |
|
VARBINARY(50) |
|
VARBINARY(MAX) |
|
具有 FILESTREAM 屬性的 VARBINARY(MAX) |
|
IMAGE |
|
TIMESTAMP |
下表顯示 DataContext.CreateDatabase 方法用於定義建立哪些 SQL 資料行型別來對應至 CLR 型別 (定義於物件模型或外部對應檔案中) 的預設型別對應。
CLR 型別 |
DataContext.CreateDatabase 所使用的預設 SQL Server 型別 |
---|---|
VARBINARY(MAX) |
|
VARBINARY(MAX) |
|
VARBINARY(MAX) |
雖然還有許多其他二進位對應可供您選擇,但是在資料庫之間來回轉譯時,某些對應可能會造成溢位或資料遺失的例外狀況。 如需詳細資訊,請參閱型別對應的執行階段行為對照表。
SQL Server FILESTREAM
從 Microsoft SQL Server 2008 開始,就提供了 VARBINARY(MAX) 資料行的 FILESTREAM 屬性。從 .NET Framework 3.5 版 SP1 開始,您就可以透過 LINQ to SQL 對應至此屬性。
雖然您可以將具有 FILESTREAM 屬性的 VARBINARY(MAX) 資料行對應至 Binary 物件,但是 DataContext.CreateDatabase 方法無法自動建立具有 FILESTREAM 屬性的資料行。 如需 FILESTREAM 的詳細資訊,請參閱《Microsoft SQL Server 線上叢書》中的 FILESTREAM 概觀。
二進位序列化
如果某個類別實作 ISerializable 介面,您就可以將物件序列化成任何 SQL 二進位欄位 (BINARY、VARBINARY 或 IMAGE)。 此物件會根據 ISerializable 介面的實作方式序列化和還原序列化。 如需詳細資訊,請參閱二進位序列化。
其他對應
下表顯示尚未提及之某些其他型別的預設型別對應。 下表顯示根據資料庫建置物件模型或外部對應檔案時,O/R 設計工具和 SQLMetal 所選取的 CLR 型別。
SQL Server 型別 |
O/R 設計工具和 SQLMetal 所使用的預設 CLR 型別對應 |
---|---|
UNIQUEIDENTIFIER |
|
SQL_VARIANT |
下表顯示 DataContext.CreateDatabase 方法用於定義建立哪些 SQL 資料行型別來對應至 CLR 型別 (定義於物件模型或外部對應檔案中) 的預設型別對應。
CLR 型別 |
DataContext.CreateDatabase 所使用的預設 SQL Server 型別 |
---|---|
UNIQUEIDENTIFIER |
|
SQL_VARIANT |
LINQ to SQL 不支援這些其他型別的任何其他型別對應。 如需詳細資訊,請參閱型別對應的執行階段行為對照表。