共用方式為


查詢中可為 Null 的運算子

可為 Null 的運算子是二進位算術或比較運算符,可在一或兩端使用可為 Null 的算術類型。 當您使用來源的數據時,會發生可為 Null 的類型,例如允許 Null 取代實際值的資料庫。 可為 Null 的運算子用於查詢表達式中。 除了算術和比較的可為 Null 運算子之外,轉換運算子也可以用來在可為 Null 的類型之間轉換。 某些查詢運算子也有可為 Null 的版本。

備註

可為 Null 的運算子通常只會用於 查詢表示式。 如果您沒有使用查詢表達式,就不需要知道或使用這些運算符。

可為 Null 運算子的數據表

下表列出 F# 中支援的可為 Null 運算子。

左側可為 Null 右側可為 Null 雙方可為 Null
?>= >=? ?>=?
?> >? ?>?
?<= <=? ?<=?
?< <? ?<?
?= =? ?=?
?<> <>? ?<>?
?+ +? ?+?
?- ?? ?-?
?* *? ?*?
?/ /? ?/?
?% %? ?%?

備註

可為 Null 的運算符會包含在命名空間 FSharp.LinqNullableOperators 模組中。 可為 Null 資料的型別為 System.Nullable<'T>

在查詢表達式中,從允許 Null 而非值之數據源選取數據時,會發生可為 Null 的類型。 在 SQL Server 資料庫中,數據表中的每個數據行都有一個屬性,指出是否允許 Null。 如果允許 Null,則從資料庫傳回的數據可以包含無法由基本數據類型表示的 Null,例如 intfloat等等。 因此,數據會以 System.Nullable<int> 取代 傳回,而不是 System.Nullable<float>floatint 實際值可以使用 屬性從 System.Nullable<'T> 物件Value取得,而且您可以藉由呼叫 HasValue 方法來判斷物件是否有System.Nullable<'T>值。 另一個有用的方法是 方法 System.Nullable<'T>.GetValueOrDefault ,可讓您取得適當類型的值或預設值。 預設值是某種形式的 「zero」 值,例如 0、0.0 或 false

可為 Null 的類型可以使用 或 floatint一般轉換運算符,轉換成不可為 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}")

另請參閱