可為 Null 的運算子是二進位算術或比較運算符,可在一或兩端使用可為 Null 的算術類型。 當您使用來源的數據時,會發生可為 Null 的類型,例如允許 Null 取代實際值的資料庫。 可為 Null 的運算子用於查詢表達式中。 除了算術和比較的可為 Null 運算子之外,轉換運算子也可以用來在可為 Null 的類型之間轉換。 某些查詢運算子也有可為 Null 的版本。
備註
可為 Null 的運算子通常只會用於 查詢表示式。 如果您沒有使用查詢表達式,就不需要知道或使用這些運算符。
可為 Null 運算子的數據表
下表列出 F# 中支援的可為 Null 運算子。
| 左側可為 Null | 右側可為 Null | 雙方可為 Null |
|---|---|---|
| ?>= | >=? | ?>=? |
| ?> | >? | ?>? |
| ?<= | <=? | ?<=? |
| ?< | <? | ?<? |
| ?= | =? | ?=? |
| ?<> | <>? | ?<>? |
| ?+ | +? | ?+? |
| ?- | ?? | ?-? |
| ?* | *? | ?*? |
| ?/ | /? | ?/? |
| ?% | %? | ?%? |
備註
可為 Null 的運算符會包含在命名空間 FSharp.Linq 的 NullableOperators 模組中。 可為 Null 資料的型別為 System.Nullable<'T>。
在查詢表達式中,從允許 Null 而非值之數據源選取數據時,會發生可為 Null 的類型。 在 SQL Server 資料庫中,數據表中的每個數據行都有一個屬性,指出是否允許 Null。 如果允許 Null,則從資料庫傳回的數據可以包含無法由基本數據類型表示的 Null,例如 int、 float等等。 因此,數據會以 System.Nullable<int> 取代 傳回,而不是 System.Nullable<float>float。int 實際值可以使用 屬性從 System.Nullable<'T> 物件Value取得,而且您可以藉由呼叫 HasValue 方法來判斷物件是否有System.Nullable<'T>值。 另一個有用的方法是 方法 System.Nullable<'T>.GetValueOrDefault ,可讓您取得適當類型的值或預設值。 預設值是某種形式的 「zero」 值,例如 0、0.0 或 false。
可為 Null 的類型可以使用 或 float等int一般轉換運算符,轉換成不可為 Null 的基本類型。 您也可以使用可為 Null 類型的轉換運算子,從一個可為 Null 的類型轉換成另一個可為 Null 的類型。 適當的轉換運算符名稱與標準運算符相同,但它們位於不同的模組中,也就是 FSharp.Linq 命名空間中的可為 Null 的模組。 一般而言,您在使用查詢表示式時開啟此命名空間。 在此情況下,您可以將前置 Nullable. 詞新增至適當的轉換運算符,以使用可為 Null 的轉換運算符,如下列程式代碼所示。
open Microsoft.FSharp.Linq
let nullableInt = new System.Nullable<int>(10)
// Use the Nullable.float conversion operator to convert from one nullable type to another nullable type.
let nullableFloat = Nullable.float nullableInt
// Use the regular non-nullable float operator to convert to a non-nullable float.
printfn $"%f{float nullableFloat}"
輸出為 10.000000。
可為 Null 數據欄位的查詢運算元,例如 sumByNullable,也存在於查詢運算式中使用。 不可為 Null 類型的查詢運算子與可為 Null 的型別不相容,因此當您使用可為 Null 的數據值時,必須使用適當查詢運算子的可為 Null 版本。 如需詳細資訊,請參閱 查詢表達式。
下列範例示範在 F# 查詢表示式中使用可為 Null 的運算子。 第一個查詢會示範如何撰寫不含可為 Null 運算符的查詢;第二個查詢會顯示使用可為 Null 運算子的對等查詢。 如需完整內容,包括如何設定資料庫以使用此範例程式代碼,請參閱逐步 解說:使用類型提供者存取 SQL Database。
open System
open System.Data
open System.Data.Linq
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
[<Generate>]
type dbSchema = SqlDataConnection<"Data Source=MYSERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;">
let db = dbSchema.GetDataContext()
query {
for row in db.Table2 do
where (row.TestData1.HasValue && row.TestData1.Value > 2)
select row
} |> Seq.iter (fun row -> printfn $"%d{row.TestData1.Value} %s{row.Name}")
query {
for row in db.Table2 do
// Use a nullable operator ?>
where (row.TestData1 ?> 2)
select row
} |> Seq.iter (fun row -> printfn "%d{row.TestData1.GetValueOrDefault()} %s{row.Name}")