Nullbara operatorer i frågor
Nullbara operatorer är binära aritmetiska operatorer eller jämförelseoperatorer som fungerar med null-aritmetiska typer på en eller båda sidor. Nullbara typer uppstår när du arbetar med data från källor, till exempel databaser som tillåter null-värden i stället för faktiska värden. Null-operatorer används i frågeuttryck. Förutom null-operatorer för aritmetik och jämförelse kan konverteringsoperatorer användas för att konvertera mellan nullbara typer. Det finns också null-versioner av vissa frågeoperatorer.
Kommentar
Nullbara operatorer används vanligtvis endast i frågeuttryck. Om du inte använder frågeuttryck behöver du inte känna till eller använda dessa operatorer.
Tabell med null-operatorer
I följande tabell visas null-operatorer som stöds i F#.
Nullbar till vänster | Nullbar till höger | Båda sidor kan inte vara null |
---|---|---|
?>= | >=? | ?>=? |
?> | >? | ?>? |
?<= | <=? | ?<=? |
?< | <? | ?<? |
?= | =? | ?=? |
?<> | <>? | ?<>? |
?+ | +? | ?+? |
?- | -? | ?-? |
?* | *? | ?*? |
?/ | /? | ?/? |
?% | %? | ?%? |
Kommentarer
De nullbara operatorerna ingår i modulen NullableOperators i namnområdet FSharp.Linq. Typen för null-data är System.Nullable<'T>
.
I frågeuttryck uppstår nullbara typer när du väljer data från en datakälla som tillåter null-värden i stället för värden. I en SQL Server-databas har varje datakolumn i en tabell ett attribut som anger om null tillåts. Om null-värden tillåts kan data som returneras från databasen innehålla nullvärden som inte kan representeras av en primitiv datatyp som int
, float
och så vidare. Därför returneras data som en System.Nullable<int>
i stället för int
, och System.Nullable<float>
i stället för float
. Det faktiska värdet kan hämtas från ett System.Nullable<'T>
objekt med hjälp Value
av egenskapen och du kan avgöra om ett System.Nullable<'T>
objekt har ett värde genom att anropa HasValue
metoden. En annan användbar metod är System.Nullable<'T>.GetValueOrDefault
metoden som gör att du kan hämta värdet eller ett standardvärde av lämplig typ. Standardvärdet är någon form av "noll"-värde, till exempel 0, 0,0 eller false
.
Nullbara typer kan konverteras till icke-nullbara primitiva typer med hjälp av vanliga konverteringsoperatorer som int
eller float
. Det går också att konvertera från en nullbar typ till en annan nullbar typ med hjälp av konverteringsoperatorerna för null-typer. Lämpliga konverteringsoperatorer har samma namn som standardoperatorerna, men de finns i en separat modul, modulen Nullable i namnområdet FSharp.Linq . Vanligtvis öppnar du det här namnområdet när du arbetar med frågeuttryck. I så fall kan du använda de nullbara konverteringsoperatorerna genom att lägga till prefixet Nullable.
till lämplig konverteringsoperator, enligt följande kod.
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}"
Utdata är 10.000000
.
Frågeoperatorer i null-datafält, till exempel sumByNullable
, finns också för användning i frågeuttryck. Frågeoperatorerna för icke-nullbara typer är inte typkompatibla med null-typer, så du måste använda den nullbara versionen av lämplig frågeoperator när du arbetar med null-datavärden. Mer information finns i Frågeuttryck.
I följande exempel visas användningen av nullbara operatorer i ett F#-frågeuttryck. Den första frågan visar hur du skulle skriva en fråga utan en null-operator. den andra frågan visar en motsvarande fråga som använder en nullbar operator. Fullständig kontext, inklusive hur du konfigurerar databasen för att använda den här exempelkoden, finns i Genomgång: Åtkomst till en SQL Database med hjälp av typproviders.
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}")