查詢表達式可讓您查詢數據源,並將數據放入所需的表單中。 查詢表達式支援 F# 中的 LINQ。
語法
query { expression }
備註
查詢表達式是類似時序表達式的計算表達式類型。 就像在序列運算式中提供程式碼來指定序列一樣,您可以在查詢表示式中提供程式碼來指定一組數據。 在序列表達式中 yield ,關鍵詞會識別要作為結果序列一部分傳回的數據。 在查詢表達式中 select ,關鍵詞會執行相同的函式。
select除了 關鍵詞之外,F# 也支援許多類似 SQL SELECT 語句部分的查詢運算符。 以下是使用 Entity Framework Core 查詢資料庫的簡單查詢運算式範例。
// F# query expression example using Entity Framework Core
open System
open System.Linq
open Microsoft.EntityFrameworkCore
// Entity type
[<CLIMutable>]
type Customer = {
CustomerID: int
CompanyName: string
ContactName: string
}
// Database context
type NorthwindContext() =
inherit DbContext()
[<DefaultValue>]
val mutable private customers: DbSet<Customer>
member this.Customers with get() = this.customers and set v = this.customers <- v
override _.OnConfiguring(optionsBuilder: DbContextOptionsBuilder) =
optionsBuilder.UseInMemoryDatabase("NorthwindDatabase") |> ignore
// Create and seed database
let db =
let context = new NorthwindContext()
context.Customers.AddRange([|
{ CustomerID = 1; CompanyName = "Alfreds Futterkiste"; ContactName = "Maria Anders" }
{ CustomerID = 2; CompanyName = "Ana Trujillo Emparedados y helados"; ContactName = "Ana Trujillo" }
{ CustomerID = 3; CompanyName = "Antonio Moreno Taquería"; ContactName = "Antonio Moreno" }
|]) |> ignore
context.SaveChanges() |> ignore
context
// A query expression
let query1 =
query {
for customer in db.Customers do
select customer
}
// Print results
query1
|> Seq.iter (fun customer -> printfn "Company: %s Contact: %s" customer.CompanyName customer.ContactName)
在先前的程式代碼範例中,查詢表達式位於大括弧中。 表達式中程式代碼的意義在於,傳回查詢結果中資料庫中 Customers 數據表中的每個客戶。 查詢表達式會傳回實作 IQueryable<T> 和 IEnumerable<T>的類型,因此可以使用 Seq 模組 進行查看,如範例所示。
每個計算表達式類型都是從產生器類別建置的。 查詢計算運算式的產生器類別為 QueryBuilder。 如需詳細資訊,請參閱 計算表達式 和 QueryBuilder 類別。
查詢運算子
查詢運算子可讓您指定查詢的詳細數據,例如將準則放在要傳回的記錄上,或指定結果的排序順序。 查詢來源必須支持查詢運算符。 如果您嘗試使用不支援的查詢運算子, System.NotSupportedException 將會擲回 。
查詢表達式中只允許可以轉譯為 SQL 的運算式。 例如,當您使用查詢運算符時,表達式中不允許任何 where 函數調用。
表 1 顯示可用的查詢運算子。 此外,請參閱 Table2,本主題稍後會比較 SQL 查詢和對等的 F# 查詢表示式。 某些類型提供者不支援某些查詢運算元。 特別是,OData 類型提供者受限於它支持的查詢運算符,因為 OData 的限制。
此資料表採用下列格式的資料庫:
下列資料表中的程式碼也會假設下列使用 Entity Framework Core 的資料庫連線程式碼。 專案應該將套件參考 Microsoft.EntityFrameworkCore 新增至 和 Microsoft.EntityFrameworkCore.InMemory (或生產案例的其他 EF Core 提供者)。 此範例會使用記憶體內部資料庫提供者進行示範,但相同的查詢語法適用於任何 EF Core 提供者 (SQL Server、PostgreSQL 等)。
// Database setup example for query expressions using Entity Framework Core
open System
open System.Linq
open Microsoft.EntityFrameworkCore
// Define entity types that map to database tables
[<CLIMutable>]
type Student = {
StudentID: int
Name: string
Age: Nullable<int>
}
[<CLIMutable>]
type Course = {
CourseID: int
CourseName: string
}
[<CLIMutable>]
type CourseSelection = {
ID: int
StudentID: int
CourseID: int
}
// Define the database context using Entity Framework Core
type SchoolContext() =
inherit DbContext()
[<DefaultValue>]
val mutable private student: DbSet<Student>
member this.Student with get() = this.student and set v = this.student <- v
[<DefaultValue>]
val mutable private course: DbSet<Course>
member this.Course with get() = this.course and set v = this.course <- v
[<DefaultValue>]
val mutable private courseSelection: DbSet<CourseSelection>
member this.CourseSelection with get() = this.courseSelection and set v = this.courseSelection <- v
override _.OnConfiguring(optionsBuilder: DbContextOptionsBuilder) =
optionsBuilder.UseInMemoryDatabase("SchoolDatabase") |> ignore
// Create and seed the database
let createAndSeedDatabase() =
let context = new SchoolContext()
// Seed data
context.Student.AddRange([|
{ StudentID = 1; Name = "Abercrombie, Kim"; Age = Nullable(10) }
{ StudentID = 2; Name = "Abolrous, Hazen"; Age = Nullable(14) }
{ StudentID = 3; Name = "Hance, Jim"; Age = Nullable(12) }
{ StudentID = 4; Name = "Adams, Terry"; Age = Nullable(12) }
{ StudentID = 5; Name = "Hansen, Claus"; Age = Nullable(11) }
{ StudentID = 6; Name = "Penor, Lori"; Age = Nullable(13) }
{ StudentID = 7; Name = "Perham, Tom"; Age = Nullable(12) }
{ StudentID = 8; Name = "Peng, Yun-Feng"; Age = Nullable() }
|]) |> ignore
context.Course.AddRange([|
{ CourseID = 1; CourseName = "Algebra I" }
{ CourseID = 2; CourseName = "Trigonometry" }
{ CourseID = 3; CourseName = "Algebra II" }
{ CourseID = 4; CourseName = "History" }
{ CourseID = 5; CourseName = "English" }
{ CourseID = 6; CourseName = "French" }
{ CourseID = 7; CourseName = "Chinese" }
|]) |> ignore
context.CourseSelection.AddRange([|
{ ID = 1; StudentID = 1; CourseID = 2 }
{ ID = 2; StudentID = 1; CourseID = 3 }
{ ID = 3; StudentID = 1; CourseID = 5 }
{ ID = 4; StudentID = 2; CourseID = 2 }
{ ID = 5; StudentID = 2; CourseID = 5 }
{ ID = 6; StudentID = 2; CourseID = 6 }
{ ID = 7; StudentID = 2; CourseID = 3 }
{ ID = 8; StudentID = 3; CourseID = 2 }
{ ID = 9; StudentID = 3; CourseID = 1 }
{ ID = 10; StudentID = 4; CourseID = 2 }
{ ID = 11; StudentID = 4; CourseID = 5 }
{ ID = 12; StudentID = 4; CourseID = 2 }
{ ID = 13; StudentID = 5; CourseID = 3 }
{ ID = 14; StudentID = 5; CourseID = 2 }
{ ID = 15; StudentID = 7; CourseID = 3 }
|]) |> ignore
context.SaveChanges() |> ignore
context
// Create the database context
let db = createAndSeedDatabase()
// Needed for some query operator examples:
let data = [ 1; 5; 7; 11; 18; 21]
資料表 1。 查詢運算子
| 操作員 | 說明 |
|---|---|
contains |
判斷選取的專案是否包含指定的專案。
|
count | 傳回選取的項目數。
|
last | 選取到目前為止選取的最後一個專案。
|
lastOrDefault | 選取到目前為止選取的最後一個專案,如果沒有找到任何元素,則選取預設值。
|
exactlyOne | 選取到目前為止選取的單一特定專案。 如果有多個元素存在,則會擲回例外狀況。
|
exactlyOneOrDefault | 選取到目前為止所選取的單一特定專案,如果找不到該專案,則選取預設值。
|
headOrDefault | 選取到目前為止選取的第一個專案,如果序列不包含任何元素,則選取預設值。
|
select | 投影到目前為止選取的每個元素。
|
where | 根據指定的述詞選取專案。
|
minBy | 為到目前為止選取的每個項目選取一個值,並傳回產生的最小值。
|
maxBy | 針對到目前為止選取的每個項目選取一個值,並傳回產生的最大值。
|
groupBy | 根據指定的索引鍵選取器,將到目前為止選取的專案分組。
|
sortBy | 依指定的排序索引鍵,依遞增順序排序到目前為止選取的專案。
|
sortByDescending | 依指定的排序索引鍵,以遞減順序排序到目前為止選取的專案。
|
thenBy | 依指定的排序索引鍵,依遞增順序執行到目前為止所選取專案的後續順序。 這個運算子只能在、 sortBysortByDescending或 thenBy之後thenByDescending使用。
|
thenByDescending | 依指定的排序索引鍵,依遞減順序執行到目前為止所選取專案的後續順序。 這個運算子只能在、 sortBysortByDescending或 thenBy之後thenByDescending使用。
|
groupValBy | 針對到目前為止選取的每個項目選取一個值,並依指定的索引鍵將元素分組。
|
join | 根據比對索引鍵,將兩組選取的值相互關聯。 請注意,在 = 登入聯結表達式前後的索引鍵順序相當重要。 在所有聯結中,如果行在符號後面 -> 分割,縮排必須至少縮排為 關鍵詞 for。
|
groupJoin | 根據比對索引鍵和將結果分組,將兩組選取的值相互關聯。 請注意,在 = 登入聯結表達式前後的索引鍵順序相當重要。
|
leftOuterJoin | 根據比對索引鍵和將結果分組,將兩組選取的值相互關聯。 如果有任何群組是空的,則會改用具有單一預設值的群組。 請注意,在 = 登入聯結表達式前後的索引鍵順序相當重要。
|
sumByNullable | 針對到目前為止選取的每個項目選取可為 Null 的值,並傳回這些值的總和。 如果任何可為 Null 的值都沒有,則會忽略該值。
|
minByNullable | 針對到目前為止選取的每個元素選取可為 Null 的值,並傳回這些值的最小值。 如果任何可為 Null 的值都沒有,則會忽略該值。
|
maxByNullable | 為到目前為止選取的每個項目選取可為 Null 的值,並傳回這些值的最大值。 如果任何可為 Null 的值都沒有,則會忽略該值。
|
averageByNullable | 針對到目前為止選取的每個項目選取可為 Null 的值,並傳回這些值的平均值。 如果任何可為 Null 的值都沒有,則會忽略該值。
|
averageBy | 為到目前為止選取的每個項目選取一個值,並傳回這些值的平均值。
|
distinct | 從到目前為止選取的項目中選取不同的專案。
|
exists | 判斷到目前為止選取的任何專案是否符合條件。
|
find | 選取到目前為止選取符合指定條件的第一個專案。
|
all | 判斷到目前為止選取的所有專案是否符合條件。
|
head | 從到目前為止選取的項目中選取第一個專案。
|
nth | 從到目前為止選取的索引中,選取位於指定索引處的專案。
|
skip | 略過到目前為止選取的指定項目數目,然後選取其餘元素。
|
skipWhile | 只要指定的條件為 true,就會略過序列中的項目,然後選取其餘元素。
|
sumBy | 為到目前為止選取的每個項目選取一個值,並傳回這些值的總和。
|
take | 從到目前為止選取的連續項目選取指定數目。
|
takeWhile | 只要指定的條件為 true,就會從序列中選取元素,然後略過其餘元素。
|
sortByNullable | 依指定的可為 Null 排序索引鍵,以遞增順序排序到目前為止選取的專案。
|
sortByNullableDescending | 依指定可為 Null 的排序索引鍵,以遞減順序排序到目前為止選取的專案。
|
thenByNullable | 依指定的可為 Null 排序索引鍵,依遞增順序執行到目前為止選取之元素的後續順序。 這個運算子只能緊sortBy接在 、、 sortByDescendingthenBy或 thenByDescending之後使用,或其可為 Null 的變體。
|
thenByNullableDescending | 依指定的可為 Null 排序索引鍵,依遞減順序執行到目前為止所選取專案的後續順序。 這個運算子只能緊sortBy接在 、、 sortByDescendingthenBy或 thenByDescending之後使用,或其可為 Null 的變體。
|
Transact-SQL 和 F# 查詢表達式的比較
下表顯示一些常見的 Transact-SQL 查詢及其在 F# 中的對等專案。 此數據表中的程式代碼也會假設與上一個數據表相同的資料庫,以及設定類型提供者的相同初始程序代碼。
表 2. Transact-SQL 和 F# 查詢表示式
| Transact-SQL (不區分大小寫) | F# 查詢表示式 (區分大小寫) |
|---|---|
從數據表中選取所有欄位。
|
|
計算數據表中的記錄。
|
|
EXISTS
|
|
分組
|
|
使用條件分組。
|
|
使用計數條件分組。
|
|
群組、計數和加總。
|
|
依計數分組、計數和排序。
|
|
IN 一組指定的值
|
|
LIKE 與 TOP。
|
|
LIKE 具有模式比對集。
|
|
LIKE 具有設定排除模式。
|
|
LIKE 在一個字段上,但選取不同的欄位。
|
|
LIKE,具有子字串搜尋。
|
|
簡單 JOIN 有兩個數據表。
|
|
LEFT JOIN 具有兩個數據表。
|
|
包含 JOIN 的 COUNT
|
|
DISTINCT
|
|
相異計數。
|
|
BETWEEN
|
|
OR
|
|
OR 使用排序
|
|
TOP、 OR和排序。
|
|
UNION 兩個查詢的 。
|
|
兩個查詢的交集。
|
|
CASE 條件。
|
|
多個案例。
|
|
多個資料表。
|
|
多個聯結。
|
|
多個左方外部聯接。
|
|
下列程式代碼可用來建立這些範例的範例資料庫。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
USE [master];
GO
IF EXISTS (SELECT * FROM sys.databases WHERE name = 'MyDatabase')
DROP DATABASE MyDatabase;
GO
-- Create the MyDatabase database.
CREATE DATABASE MyDatabase COLLATE SQL_Latin1_General_CP1_CI_AS;
GO
-- Specify a simple recovery model
-- to keep the log growth to a minimum.
ALTER DATABASE MyDatabase
SET RECOVERY SIMPLE;
GO
USE MyDatabase;
GO
CREATE TABLE [dbo].[Course] (
[CourseID] INT NOT NULL,
[CourseName] NVARCHAR (50) NOT NULL,
PRIMARY KEY CLUSTERED ([CourseID] ASC)
);
CREATE TABLE [dbo].[Student] (
[StudentID] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Age] INT NULL,
PRIMARY KEY CLUSTERED ([StudentID] ASC)
);
CREATE TABLE [dbo].[CourseSelection] (
[ID] INT NOT NULL,
[StudentID] INT NOT NULL,
[CourseID] INT NOT NULL,
PRIMARY KEY CLUSTERED ([ID] ASC),
CONSTRAINT [FK_CourseSelection_ToTable] FOREIGN KEY ([StudentID]) REFERENCES [dbo].[Student] ([StudentID]) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT [FK_CourseSelection_Course_1] FOREIGN KEY ([CourseID]) REFERENCES [dbo].[Course] ([CourseID]) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE [dbo].[LastStudent] (
[StudentID] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Age] INT NULL,
PRIMARY KEY CLUSTERED ([StudentID] ASC)
);
-- Insert data into the tables.
USE MyDatabase
INSERT INTO Course (CourseID, CourseName)
VALUES(1, 'Algebra I');
INSERT INTO Course (CourseID, CourseName)
VALUES(2, 'Trigonometry');
INSERT INTO Course (CourseID, CourseName)
VALUES(3, 'Algebra II');
INSERT INTO Course (CourseID, CourseName)
VALUES(4, 'History');
INSERT INTO Course (CourseID, CourseName)
VALUES(5, 'English');
INSERT INTO Course (CourseID, CourseName)
VALUES(6, 'French');
INSERT INTO Course (CourseID, CourseName)
VALUES(7, 'Chinese');
INSERT INTO Student (StudentID, Name, Age)
VALUES(1, 'Abercrombie, Kim', 10);
INSERT INTO Student (StudentID, Name, Age)
VALUES(2, 'Abolrous, Hazen', 14);
INSERT INTO Student (StudentID, Name, Age)
VALUES(3, 'Hance, Jim', 12);
INSERT INTO Student (StudentID, Name, Age)
VALUES(4, 'Adams, Terry', 12);
INSERT INTO Student (StudentID, Name, Age)
VALUES(5, 'Hansen, Claus', 11);
INSERT INTO Student (StudentID, Name, Age)
VALUES(6, 'Penor, Lori', 13);
INSERT INTO Student (StudentID, Name, Age)
VALUES(7, 'Perham, Tom', 12);
INSERT INTO Student (StudentID, Name, Age)
VALUES(8, 'Peng, Yun-Feng', NULL);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(1, 1, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(2, 1, 3);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(3, 1, 5);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(4, 2, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(5, 2, 5);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(6, 2, 6);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(7, 2, 3);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(8, 3, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(9, 3, 1);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(10, 4, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(11, 4, 5);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(12, 4, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(13, 5, 3);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(14, 5, 2);
INSERT INTO CourseSelection (ID, StudentID, CourseID)
VALUES(15, 7, 3);
下列程式代碼包含本主題中顯示的範例程序代碼。
open System
open System.Linq
// Define simple data types to represent our sample database
type Student = {
StudentID: int
Name: string
Age: int option
}
type Course = {
CourseID: int
CourseName: string
}
type CourseSelection = {
ID: int
StudentID: int
CourseID: int
}
// Sample data
let students = [
{ StudentID = 1; Name = "Abercrombie, Kim"; Age = Some 10 }
{ StudentID = 2; Name = "Abolrous, Hazen"; Age = Some 14 }
{ StudentID = 3; Name = "Hance, Jim"; Age = Some 12 }
{ StudentID = 4; Name = "Adams, Terry"; Age = Some 12 }
{ StudentID = 5; Name = "Hansen, Claus"; Age = Some 11 }
{ StudentID = 6; Name = "Penor, Lori"; Age = Some 13 }
{ StudentID = 7; Name = "Perham, Tom"; Age = Some 12 }
{ StudentID = 8; Name = "Peng, Yun-Feng"; Age = None }
]
let courses = [
{ CourseID = 1; CourseName = "Algebra I" }
{ CourseID = 2; CourseName = "Trigonometry" }
{ CourseID = 3; CourseName = "Algebra II" }
{ CourseID = 4; CourseName = "History" }
{ CourseID = 5; CourseName = "English" }
{ CourseID = 6; CourseName = "French" }
{ CourseID = 7; CourseName = "Chinese" }
]
let courseSelections = [
{ ID = 1; StudentID = 1; CourseID = 2 }
{ ID = 2; StudentID = 1; CourseID = 3 }
{ ID = 3; StudentID = 1; CourseID = 5 }
{ ID = 4; StudentID = 2; CourseID = 2 }
{ ID = 5; StudentID = 2; CourseID = 5 }
{ ID = 6; StudentID = 2; CourseID = 6 }
{ ID = 7; StudentID = 2; CourseID = 3 }
{ ID = 8; StudentID = 3; CourseID = 2 }
{ ID = 9; StudentID = 3; CourseID = 1 }
{ ID = 10; StudentID = 4; CourseID = 2 }
{ ID = 11; StudentID = 4; CourseID = 5 }
{ ID = 12; StudentID = 4; CourseID = 2 }
{ ID = 13; StudentID = 5; CourseID = 3 }
{ ID = 14; StudentID = 5; CourseID = 2 }
{ ID = 15; StudentID = 7; CourseID = 3 }
]
// Convert to queryable collections for LINQ operations
let db.Student = students.AsQueryable()
let coursesQueryable = courses.AsQueryable()
let courseSelectionsQueryable = courseSelections.AsQueryable()
let data = [1; 5; 7; 11; 18; 21]
type Nullable<'T when 'T : ( new : unit -> 'T) and 'T : struct and 'T :> ValueType > with
member this.Print() =
if this.HasValue then this.Value.ToString()
else "NULL"
printfn "\ncontains query operator"
query {
for student in db.Student do
select student.Age.Value
contains 11
}
|> printfn "Is at least one student age 11? %b"
printfn "\ncount query operator"
query {
for student in db.Student do
select student
count
}
|> printfn "Number of students: %d"
printfn "\nlast query operator."
let num =
query {
for number in data do
sortBy number
last
}
printfn "Last number: %d" num
open Microsoft.FSharp.Linq
printfn "\nlastOrDefault query operator."
query {
for number in data do
sortBy number
lastOrDefault
}
|> printfn "lastOrDefault: %d"
printfn "\nexactlyOne query operator."
let student2 =
query {
for student in db.Student do
where (student.StudentID = 1)
select student
exactlyOne
}
printfn "Student with StudentID = 1 is %s" student2.Name
printfn "\nexactlyOneOrDefault query operator."
let student3 =
query {
for student in db.Student do
where (student.StudentID = 1)
select student
exactlyOneOrDefault
}
printfn "Student with StudentID = 1 is %s" student3.Name
printfn "\nheadOrDefault query operator."
let student4 =
query {
for student in db.Student do
select student
headOrDefault
}
printfn "head student is %s" student4.Name
printfn "\nselect query operator."
query {
for student in db.Student do
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.StudentID student.Name)
printfn "\nwhere query operator."
query {
for student in db.Student do
where (student.StudentID > 4)
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.StudentID student.Name)
printfn "\nminBy query operator."
let student5 =
query {
for student in db.Student do
minBy student.StudentID
}
printfn "\nmaxBy query operator."
let student6 =
query {
for student in db.Student do
maxBy student.StudentID
}
printfn "\ngroupBy query operator."
query {
for student in db.Student do
groupBy student.Age into g
select (g.Key, g.Count())
}
|> Seq.iter (fun (age, count) -> printfn "Age: %s Count at that age: %d" (age.Print()) count)
printfn "\nsortBy query operator."
query {
for student in db.Student do
sortBy student.Name
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.StudentID student.Name)
printfn "\nsortByDescending query operator."
query {
for student in db.Student do
sortByDescending student.Name
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.StudentID student.Name)
printfn "\nthenBy query operator."
query {
for student in db.Student do
where student.Age.HasValue
sortBy student.Age.Value
thenBy student.Name
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.Age.Value student.Name)
printfn "\nthenByDescending query operator."
query {
for student in db.Student do
where student.Age.HasValue
sortBy student.Age.Value
thenByDescending student.Name
select student
}
|> Seq.iter (fun student -> printfn "StudentID, Name: %d %s" student.Age.Value student.Name)
printfn "\ngroupValBy query operator."
query {
for student in db.Student do
groupValBy student.Name student.Age into g
select (g, g.Key, g.Count())
}
|> Seq.iter (fun (group, age, count) ->
printfn "Age: %s Count at that age: %d" (age.Print()) count
group |> Seq.iter (fun name -> printfn "Name: %s" name))
printfn "\n sumByNullable query operator"
query {
for student in db.Student do
sumByNullable student.Age
}
|> (fun sum -> printfn "Sum of ages: %s" (sum.Print()))
printfn "\n minByNullable"
query {
for student in db.Student do
minByNullable student.Age
}
|> (fun age -> printfn "Minimum age: %s" (age.Print()))
printfn "\n maxByNullable"
query {
for student in db.Student do
maxByNullable student.Age
}
|> (fun age -> printfn "Maximum age: %s" (age.Print()))
printfn "\n averageBy"
query {
for student in db.Student do
averageBy (float student.StudentID)
}
|> printfn "Average student ID: %f"
printfn "\n averageByNullable"
query {
for student in db.Student do
averageByNullable (Nullable.float student.Age)
}
|> (fun avg -> printfn "Average age: %s" (avg.Print()))
printfn "\n find query operator"
query {
for student in db.Student do
find (student.Name = "Abercrombie, Kim")
}
|> (fun student -> printfn "Found a match with StudentID = %d" student.StudentID)
printfn "\n all query operator"
query {
for student in db.Student do
all (SqlMethods.Like(student.Name, "%,%"))
}
|> printfn "Do all students have a comma in the name? %b"
printfn "\n head query operator"
query {
for student in db.Student do
head
}
|> (fun student -> printfn "Found the head student with StudentID = %d" student.StudentID)
printfn "\n nth query operator"
query {
for numbers in data do
nth 3
}
|> printfn "Third number is %d"
printfn "\n skip query operator"
query {
for student in db.Student do
skip 1
}
|> Seq.iter (fun student -> printfn "StudentID = %d" student.StudentID)
printfn "\n skipWhile query operator"
query {
for number in data do
skipWhile (number < 3)
select number
}
|> Seq.iter (fun number -> printfn "Number = %d" number)
printfn "\n sumBy query operator"
query {
for student in db.Student do
sumBy student.StudentID
}
|> printfn "Sum of student IDs: %d"
printfn "\n take query operator"
query {
for student in db.Student do
select student
take 2
}
|> Seq.iter (fun student -> printfn "StudentID = %d" student.StudentID)
printfn "\n takeWhile query operator"
query {
for number in data do
takeWhile (number < 10)
}
|> Seq.iter (fun number -> printfn "Number = %d" number)
printfn "\n sortByNullable query operator"
query {
for student in db.Student do
sortByNullable student.Age
select student
}
|> Seq.iter (fun student ->
printfn "StudentID, Name, Age: %d %s %s" student.StudentID student.Name (student.Age.Print()))
printfn "\n sortByNullableDescending query operator"
query {
for student in db.Student do
sortByNullableDescending student.Age
select student
}
|> Seq.iter (fun student ->
printfn "StudentID, Name, Age: %d %s %s" student.StudentID student.Name (student.Age.Print()))
printfn "\n thenByNullable query operator"
query {
for student in db.Student do
sortBy student.Name
thenByNullable student.Age
select student
}
|> Seq.iter (fun student ->
printfn "StudentID, Name, Age: %d %s %s" student.StudentID student.Name (student.Age.Print()))
printfn "\n thenByNullableDescending query operator"
query {
for student in db.Student do
sortBy student.Name
thenByNullableDescending student.Age
select student
}
|> Seq.iter (fun student ->
printfn "StudentID, Name, Age: %d %s %s" student.StudentID student.Name (student.Age.Print()))
printfn "All students: "
query {
for student in db.Student do
select student
}
|> Seq.iter (fun student -> printfn "%s %d %s" student.Name student.StudentID (student.Age.Print()))
printfn "\nCount of students: "
query {
for student in db.Student do
count
}
|> (fun count -> printfn "Student count: %d" count)
printfn "\nExists."
query {
for student in db.Student do
where
(query {
for courseSelection in db.CourseSelection do
exists (courseSelection.StudentID = student.StudentID) })
select student
}
|> Seq.iter (fun student -> printfn "%A" student.Name)
printfn "\n Group by age and count"
query {
for n in db.Student do
groupBy n.Age into g
select (g.Key, g.Count())
}
|> Seq.iter (fun (age, count) -> printfn "%s %d" (age.Print()) count)
printfn "\n Group value by age."
query {
for n in db.Student do
groupValBy n.Age n.Age into g
select (g.Key, g.Count())
}
|> Seq.iter (fun (age, count) -> printfn "%s %d" (age.Print()) count)
printfn "\nGroup students by age where age > 10."
query {
for student in db.Student do
groupBy student.Age into g
where (g.Key.HasValue && g.Key.Value > 10)
select (g, g.Key)
}
|> Seq.iter (fun (students, age) ->
printfn "Age: %s" (age.Value.ToString())
students
|> Seq.iter (fun student -> printfn "%s" student.Name))
printfn "\nGroup students by age and print counts of number of students at each age with more than 1 student."
query {
for student in db.Student do
groupBy student.Age into group
where (group.Count() > 1)
select (group.Key, group.Count())
}
|> Seq.iter (fun (age, ageCount) ->
printfn "Age: %s Count: %d" (age.Print()) ageCount)
printfn "\nGroup students by age and sum ages."
query {
for student in db.Student do
groupBy student.Age into g
let total = query { for student in g do sumByNullable student.Age }
select (g.Key, g.Count(), total)
}
|> Seq.iter (fun (age, count, total) ->
printfn "Age: %d" (age.GetValueOrDefault())
printfn "Count: %d" count
printfn "Total years: %s" (total.ToString()))
printfn "\nGroup students by age and count number of students at each age, and display all with count > 1 in descending order of count."
query {
for student in db.Student do
groupBy student.Age into g
where (g.Count() > 1)
sortByDescending (g.Count())
select (g.Key, g.Count())
}
|> Seq.iter (fun (age, myCount) ->
printfn "Age: %s" (age.Print())
printfn "Count: %d" myCount)
printfn "\n Select students from a set of IDs"
let idList = [1; 2; 5; 10]
let idQuery =
query { for id in idList do select id }
query {
for student in db.Student do
where (idQuery.Contains(student.StudentID))
select student
}
|> Seq.iter (fun student ->
printfn "Name: %s" student.Name)
printfn "\nLook for students with Name match _e%% pattern and take first two."
query {
for student in db.Student do
where (SqlMethods.Like( student.Name, "_e%") )
select student
take 2
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nLook for students with Name matching [abc]%% pattern."
query {
for student in db.Student do
where (SqlMethods.Like( student.Name, "[abc]%") )
select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nLook for students with name matching [^abc]%% pattern."
query {
for student in db.Student do
where (SqlMethods.Like( student.Name, "[^abc]%") )
select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nLook for students with name matching [^abc]%% pattern and select ID."
query {
for n in db.Student do
where (SqlMethods.Like( n.Name, "[^abc]%") )
select n.StudentID
}
|> Seq.iter (fun id -> printfn "%d" id)
printfn "\n Using Contains as a query filter."
query {
for student in db.Student do
where (student.Name.Contains("a"))
select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nSearching for names from a list."
let names = [|"a";"b";"c"|]
query {
for student in db.Student do
if names.Contains (student.Name) then select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\nJoin Student and CourseSelection tables."
query {
for student in db.Student do
join selection in db.CourseSelection
on (student.StudentID = selection.StudentID)
select (student, selection)
}
|> Seq.iter (fun (student, selection) -> printfn "%d %s %d" student.StudentID student.Name selection.CourseID)
printfn "\nLeft Join Student and CourseSelection tables."
query {
for student in db.Student do
leftOuterJoin selection in db.CourseSelection
on (student.StudentID = selection.StudentID) into result
for selection in result.DefaultIfEmpty() do
select (student, selection)
}
|> Seq.iter (fun (student, selection) ->
let selectionID, studentID, courseID =
match selection with
| null -> "NULL", "NULL", "NULL"
| sel -> (sel.ID.ToString(), sel.StudentID.ToString(), sel.CourseID.ToString())
printfn "%d %s %d %s %s %s" student.StudentID student.Name (student.Age.GetValueOrDefault()) selectionID studentID courseID)
printfn "\nJoin with count"
query {
for n in db.Student do
join e in db.CourseSelection
on (n.StudentID = e.StudentID)
count
}
|> printfn "%d"
printfn "\n Join with distinct."
query {
for student in db.Student do
join selection in db.CourseSelection
on (student.StudentID = selection.StudentID)
distinct
}
|> Seq.iter (fun (student, selection) -> printfn "%s %d" student.Name selection.CourseID)
printfn "\n Join with distinct and count."
query {
for n in db.Student do
join e in db.CourseSelection
on (n.StudentID = e.StudentID)
distinct
count
}
|> printfn "%d"
printfn "\n Selecting students with age between 10 and 15."
query {
for student in db.Student do
where (student.Age.Value >= 10 && student.Age.Value < 15)
select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\n Selecting students with age either 11 or 12."
query {
for student in db.Student do
where (student.Age.Value = 11 || student.Age.Value = 12)
select student
}
|> Seq.iter (fun student -> printfn "%s" student.Name)
printfn "\n Selecting students in a certain age range and sorting."
query {
for n in db.Student do
where (n.Age.Value = 12 || n.Age.Value = 13)
sortByNullableDescending n.Age
select n
}
|> Seq.iter (fun student -> printfn "%s %s" student.Name (student.Age.Print()))
printfn "\n Selecting students with certain ages, taking account of possibility of nulls."
query {
for student in db.Student do
where
((student.Age.HasValue && student.Age.Value = 11) ||
(student.Age.HasValue && student.Age.Value = 12))
sortByDescending student.Name
select student.Name
take 2
}
|> Seq.iter (fun name -> printfn "%s" name)
printfn "\n Union of two queries."
module Queries =
let query1 = query {
for n in db.Student do
select (n.Name, n.Age)
}
let query2 = query {
for n in db.LastStudent do
select (n.Name, n.Age)
}
query2.Union (query1)
|> Seq.iter (fun (name, age) -> printfn "%s %s" name (age.Print()))
printfn "\n Intersect of two queries."
module Queries2 =
let query1 = query {
for n in db.Student do
select (n.Name, n.Age)
}
let query2 = query {
for n in db.LastStudent do
select (n.Name, n.Age)
}
query1.Intersect(query2)
|> Seq.iter (fun (name, age) -> printfn "%s %s" name (age.Print()))
printfn "\n Using if statement to alter results for special value."
query {
for student in db.Student do
select
(if student.Age.HasValue && student.Age.Value = -1 then
(student.StudentID, System.Nullable<int>(100), student.Age)
else (student.StudentID, student.Age, student.Age))
}
|> Seq.iter (fun (id, value, age) -> printfn "%d %s %s" id (value.Print()) (age.Print()))
printfn "\n Using if statement to alter results special values."
query {
for student in db.Student do
select
(if student.Age.HasValue && student.Age.Value = -1 then
(student.StudentID, System.Nullable<int>(100), student.Age)
elif student.Age.HasValue && student.Age.Value = 0 then
(student.StudentID, System.Nullable<int>(100), student.Age)
else (student.StudentID, student.Age, student.Age))
}
|> Seq.iter (fun (id, value, age) -> printfn "%d %s %s" id (value.Print()) (age.Print()))
printfn "\n Multiple table select."
query {
for student in db.Student do
for course in db.Course do
select (student, course)
}
|> Seq.iteri (fun index (student, course) ->
if index = 0 then
printfn "StudentID Name Age CourseID CourseName"
printfn "%d %s %s %d %s" student.StudentID student.Name (student.Age.Print()) course.CourseID course.CourseName)
printfn "\nMultiple Joins"
query {
for student in db.Student do
join courseSelection in db.CourseSelection
on (student.StudentID = courseSelection.StudentID)
join course in db.Course
on (courseSelection.CourseID = course.CourseID)
select (student.Name, course.CourseName)
}
|> Seq.iter (fun (studentName, courseName) -> printfn "%s %s" studentName courseName)
printfn "\nMultiple Left Outer Joins"
query {
for student in db.Student do
leftOuterJoin courseSelection in db.CourseSelection
on (student.StudentID = courseSelection.StudentID) into g1
for courseSelection in g1.DefaultIfEmpty() do
leftOuterJoin course in db.Course
on (courseSelection.CourseID = course.CourseID) into g2
for course in g2.DefaultIfEmpty() do
select (student.Name, course.CourseName)
}
|> Seq.iter (fun (studentName, courseName) -> printfn "%s %s" studentName courseName)
以下是此程式代碼在 F# Interactive 中執行時的完整輸出。
contains query operator
Is at least one student age 11? true
count query operator
Number of students: 8
last query operator.
Last number: 21
lastOrDefault query operator.
lastOrDefault: 21
exactlyOne query operator.
Student with StudentID = 1 is Abercrombie, Kim
exactlyOneOrDefault query operator.
Student with StudentID = 1 is Abercrombie, Kim
headOrDefault query operator.
head student is Abercrombie, Kim
select query operator.
StudentID, Name: 1 Abercrombie, Kim
StudentID, Name: 2 Abolrous, Hazen
StudentID, Name: 3 Hance, Jim
StudentID, Name: 4 Adams, Terry
StudentID, Name: 5 Hansen, Claus
StudentID, Name: 6 Penor, Lori
StudentID, Name: 7 Perham, Tom
StudentID, Name: 8 Peng, Yun-Feng
where query operator.
StudentID, Name: 5 Hansen, Claus
StudentID, Name: 6 Penor, Lori
StudentID, Name: 7 Perham, Tom
StudentID, Name: 8 Peng, Yun-Feng
minBy query operator.
maxBy query operator.
groupBy query operator.
Age: NULL Count at that age: 1
Age: 10 Count at that age: 1
Age: 11 Count at that age: 1
Age: 12 Count at that age: 3
Age: 13 Count at that age: 1
Age: 14 Count at that age: 1
sortBy query operator.
StudentID, Name: 1 Abercrombie, Kim
StudentID, Name: 2 Abolrous, Hazen
StudentID, Name: 4 Adams, Terry
StudentID, Name: 3 Hance, Jim
StudentID, Name: 5 Hansen, Claus
StudentID, Name: 8 Peng, Yun-Feng
StudentID, Name: 6 Penor, Lori
StudentID, Name: 7 Perham, Tom
sortByDescending query operator.
StudentID, Name: 7 Perham, Tom
StudentID, Name: 6 Penor, Lori
StudentID, Name: 8 Peng, Yun-Feng
StudentID, Name: 5 Hansen, Claus
StudentID, Name: 3 Hance, Jim
StudentID, Name: 4 Adams, Terry
StudentID, Name: 2 Abolrous, Hazen
StudentID, Name: 1 Abercrombie, Kim
thenBy query operator.
StudentID, Name: 10 Abercrombie, Kim
StudentID, Name: 11 Hansen, Claus
StudentID, Name: 12 Adams, Terry
StudentID, Name: 12 Hance, Jim
StudentID, Name: 12 Perham, Tom
StudentID, Name: 13 Penor, Lori
StudentID, Name: 14 Abolrous, Hazen
thenByDescending query operator.
StudentID, Name: 10 Abercrombie, Kim
StudentID, Name: 11 Hansen, Claus
StudentID, Name: 12 Perham, Tom
StudentID, Name: 12 Hance, Jim
StudentID, Name: 12 Adams, Terry
StudentID, Name: 13 Penor, Lori
StudentID, Name: 14 Abolrous, Hazen
groupValBy query operator.
Age: NULL Count at that age: 1
Name: Peng, Yun-Feng
Age: 10 Count at that age: 1
Name: Abercrombie, Kim
Age: 11 Count at that age: 1
Name: Hansen, Claus
Age: 12 Count at that age: 3
Name: Hance, Jim
Name: Adams, Terry
Name: Perham, Tom
Age: 13 Count at that age: 1
Name: Penor, Lori
Age: 14 Count at that age: 1
Name: Abolrous, Hazen
sumByNullable query operator
Sum of ages: 84
minByNullable
Minimum age: 10
maxByNullable
Maximum age: 14
averageBy
Average student ID: 4.500000
averageByNullable
Average age: 12
find query operator
Found a match with StudentID = 1
all query operator
Do all students have a comma in the name? true
head query operator
Found the head student with StudentID = 1
nth query operator
Third number is 11
skip query operator
StudentID = 2
StudentID = 3
StudentID = 4
StudentID = 5
StudentID = 6
StudentID = 7
StudentID = 8
skipWhile query operator
Number = 5
Number = 7
Number = 11
Number = 18
Number = 21
sumBy query operator
Sum of student IDs: 36
take query operator
StudentID = 1
StudentID = 2
takeWhile query operator
Number = 1
Number = 5
Number = 7
sortByNullable query operator
StudentID, Name, Age: 8 Peng, Yun-Feng NULL
StudentID, Name, Age: 1 Abercrombie, Kim 10
StudentID, Name, Age: 5 Hansen, Claus 11
StudentID, Name, Age: 7 Perham, Tom 12
StudentID, Name, Age: 3 Hance, Jim 12
StudentID, Name, Age: 4 Adams, Terry 12
StudentID, Name, Age: 6 Penor, Lori 13
StudentID, Name, Age: 2 Abolrous, Hazen 14
sortByNullableDescending query operator
StudentID, Name, Age: 2 Abolrous, Hazen 14
StudentID, Name, Age: 6 Penor, Lori 13
StudentID, Name, Age: 7 Perham, Tom 12
StudentID, Name, Age: 3 Hance, Jim 12
StudentID, Name, Age: 4 Adams, Terry 12
StudentID, Name, Age: 5 Hansen, Claus 11
StudentID, Name, Age: 1 Abercrombie, Kim 10
StudentID, Name, Age: 8 Peng, Yun-Feng NULL
thenByNullable query operator
StudentID, Name, Age: 1 Abercrombie, Kim 10
StudentID, Name, Age: 2 Abolrous, Hazen 14
StudentID, Name, Age: 4 Adams, Terry 12
StudentID, Name, Age: 3 Hance, Jim 12
StudentID, Name, Age: 5 Hansen, Claus 11
StudentID, Name, Age: 8 Peng, Yun-Feng NULL
StudentID, Name, Age: 6 Penor, Lori 13
StudentID, Name, Age: 7 Perham, Tom 12
thenByNullableDescending query operator
StudentID, Name, Age: 1 Abercrombie, Kim 10
StudentID, Name, Age: 2 Abolrous, Hazen 14
StudentID, Name, Age: 4 Adams, Terry 12
StudentID, Name, Age: 3 Hance, Jim 12
StudentID, Name, Age: 5 Hansen, Claus 11
StudentID, Name, Age: 8 Peng, Yun-Feng NULL
StudentID, Name, Age: 6 Penor, Lori 13
StudentID, Name, Age: 7 Perham, Tom 12
All students:
Abercrombie, Kim 1 10
Abolrous, Hazen 2 14
Hance, Jim 3 12
Adams, Terry 4 12
Hansen, Claus 5 11
Penor, Lori 6 13
Perham, Tom 7 12
Peng, Yun-Feng 8 NULL
Count of students:
Student count: 8
Exists.
"Abercrombie, Kim"
"Abolrous, Hazen"
"Hance, Jim"
"Adams, Terry"
"Hansen, Claus"
"Perham, Tom"
Group by age and count
NULL 1
10 1
11 1
12 3
13 1
14 1
Group value by age.
NULL 1
10 1
11 1
12 3
13 1
14 1
Group students by age where age > 10.
Age: 11
Hansen, Claus
Age: 12
Hance, Jim
Adams, Terry
Perham, Tom
Age: 13
Penor, Lori
Age: 14
Abolrous, Hazen
Group students by age and print counts of number of students at each age with more than 1 student.
Age: 12 Count: 3
Group students by age and sum ages.
Age: 0
Count: 1
Total years:
Age: 10
Count: 1
Total years: 10
Age: 11
Count: 1
Total years: 11
Age: 12
Count: 3
Total years: 36
Age: 13
Count: 1
Total years: 13
Age: 14
Count: 1
Total years: 14
Group students by age and count number of students at each age, and display all with count > 1 in descending order of count.
Age: 12
Count: 3
Select students from a set of IDs
Name: Abercrombie, Kim
Name: Abolrous, Hazen
Name: Hansen, Claus
Look for students with Name match _e% pattern and take first two.
Penor, Lori
Perham, Tom
Look for students with Name matching [abc]% pattern.
Abercrombie, Kim
Abolrous, Hazen
Adams, Terry
Look for students with name matching [^abc]% pattern.
Hance, Jim
Hansen, Claus
Penor, Lori
Perham, Tom
Peng, Yun-Feng
Look for students with name matching [^abc]% pattern and select ID.
3
5
6
7
8
Using Contains as a query filter.
Abercrombie, Kim
Abolrous, Hazen
Hance, Jim
Adams, Terry
Hansen, Claus
Perham, Tom
Searching for names from a list.
Join Student and CourseSelection tables.
2 Abolrous, Hazen 2
3 Hance, Jim 3
5 Hansen, Claus 5
2 Abolrous, Hazen 2
5 Hansen, Claus 5
6 Penor, Lori 6
3 Hance, Jim 3
2 Abolrous, Hazen 2
1 Abercrombie, Kim 1
2 Abolrous, Hazen 2
5 Hansen, Claus 5
2 Abolrous, Hazen 2
3 Hance, Jim 3
2 Abolrous, Hazen 2
3 Hance, Jim 3
Left Join Student and CourseSelection tables.
1 Abercrombie, Kim 10 9 3 1
2 Abolrous, Hazen 14 1 1 2
2 Abolrous, Hazen 14 4 2 2
2 Abolrous, Hazen 14 8 3 2
2 Abolrous, Hazen 14 10 4 2
2 Abolrous, Hazen 14 12 4 2
2 Abolrous, Hazen 14 14 5 2
3 Hance, Jim 12 2 1 3
3 Hance, Jim 12 7 2 3
3 Hance, Jim 12 13 5 3
3 Hance, Jim 12 15 7 3
4 Adams, Terry 12 NULL NULL NULL
5 Hansen, Claus 11 3 1 5
5 Hansen, Claus 11 5 2 5
5 Hansen, Claus 11 11 4 5
6 Penor, Lori 13 6 2 6
7 Perham, Tom 12 NULL NULL NULL
8 Peng, Yun-Feng 0 NULL NULL NULL
Join with count
15
Join with distinct.
Abercrombie, Kim 2
Abercrombie, Kim 3
Abercrombie, Kim 5
Abolrous, Hazen 2
Abolrous, Hazen 5
Abolrous, Hazen 6
Abolrous, Hazen 3
Hance, Jim 2
Hance, Jim 1
Adams, Terry 2
Adams, Terry 5
Adams, Terry 2
Hansen, Claus 3
Hansen, Claus 2
Perham, Tom 3
Join with distinct and count.
15
Selecting students with age between 10 and 15.
Abercrombie, Kim
Abolrous, Hazen
Hance, Jim
Adams, Terry
Hansen, Claus
Penor, Lori
Perham, Tom
Selecting students with age either 11 or 12.
Hance, Jim
Adams, Terry
Hansen, Claus
Perham, Tom
Selecting students in a certain age range and sorting.
Penor, Lori 13
Perham, Tom 12
Hance, Jim 12
Adams, Terry 12
Selecting students with certain ages, taking account of possibility of nulls.
Hance, Jim
Adams, Terry
Union of two queries.
Abercrombie, Kim 10
Abolrous, Hazen 14
Hance, Jim 12
Adams, Terry 12
Hansen, Claus 11
Penor, Lori 13
Perham, Tom 12
Peng, Yun-Feng NULL
Intersect of two queries.
Using if statement to alter results for special value.
1 10 10
2 14 14
3 12 12
4 12 12
5 11 11
6 13 13
7 12 12
8 NULL NULL
Using if statement to alter results special values.
1 10 10
2 14 14
3 12 12
4 12 12
5 11 11
6 13 13
7 12 12
8 NULL NULL
Multiple table select.
StudentID Name Age CourseID CourseName
1 Abercrombie, Kim 10 1 Algebra I
2 Abolrous, Hazen 14 1 Algebra I
3 Hance, Jim 12 1 Algebra I
4 Adams, Terry 12 1 Algebra I
5 Hansen, Claus 11 1 Algebra I
6 Penor, Lori 13 1 Algebra I
7 Perham, Tom 12 1 Algebra I
8 Peng, Yun-Feng NULL 1 Algebra I
1 Abercrombie, Kim 10 2 Trigonometry
2 Abolrous, Hazen 14 2 Trigonometry
3 Hance, Jim 12 2 Trigonometry
4 Adams, Terry 12 2 Trigonometry
5 Hansen, Claus 11 2 Trigonometry
6 Penor, Lori 13 2 Trigonometry
7 Perham, Tom 12 2 Trigonometry
8 Peng, Yun-Feng NULL 2 Trigonometry
1 Abercrombie, Kim 10 3 Algebra II
2 Abolrous, Hazen 14 3 Algebra II
3 Hance, Jim 12 3 Algebra II
4 Adams, Terry 12 3 Algebra II
5 Hansen, Claus 11 3 Algebra II
6 Penor, Lori 13 3 Algebra II
7 Perham, Tom 12 3 Algebra II
8 Peng, Yun-Feng NULL 3 Algebra II
1 Abercrombie, Kim 10 4 History
2 Abolrous, Hazen 14 4 History
3 Hance, Jim 12 4 History
4 Adams, Terry 12 4 History
5 Hansen, Claus 11 4 History
6 Penor, Lori 13 4 History
7 Perham, Tom 12 4 History
8 Peng, Yun-Feng NULL 4 History
1 Abercrombie, Kim 10 5 English
2 Abolrous, Hazen 14 5 English
3 Hance, Jim 12 5 English
4 Adams, Terry 12 5 English
5 Hansen, Claus 11 5 English
6 Penor, Lori 13 5 English
7 Perham, Tom 12 5 English
8 Peng, Yun-Feng NULL 5 English
1 Abercrombie, Kim 10 6 French
2 Abolrous, Hazen 14 6 French
3 Hance, Jim 12 6 French
4 Adams, Terry 12 6 French
5 Hansen, Claus 11 6 French
6 Penor, Lori 13 6 French
7 Perham, Tom 12 6 French
8 Peng, Yun-Feng NULL 6 French
1 Abercrombie, Kim 10 7 Chinese
2 Abolrous, Hazen 14 7 Chinese
3 Hance, Jim 12 7 Chinese
4 Adams, Terry 12 7 Chinese
5 Hansen, Claus 11 7 Chinese
6 Penor, Lori 13 7 Chinese
7 Perham, Tom 12 7 Chinese
8 Peng, Yun-Feng NULL 7 Chinese
Multiple Joins
Abercrombie, Kim Trigonometry
Abercrombie, Kim Algebra II
Abercrombie, Kim English
Abolrous, Hazen Trigonometry
Abolrous, Hazen English
Abolrous, Hazen French
Abolrous, Hazen Algebra II
Hance, Jim Trigonometry
Hance, Jim Algebra I
Adams, Terry Trigonometry
Adams, Terry English
Adams, Terry Trigonometry
Hansen, Claus Algebra II
Hansen, Claus Trigonometry
Perham, Tom Algebra II
Multiple Left Outer Joins
Abercrombie, Kim Trigonometry
Abercrombie, Kim Algebra II
Abercrombie, Kim English
Abolrous, Hazen Trigonometry
Abolrous, Hazen English
Abolrous, Hazen French
Abolrous, Hazen Algebra II
Hance, Jim Trigonometry
Hance, Jim Algebra I
Adams, Terry Trigonometry
Adams, Terry English
Adams, Terry Trigonometry
Hansen, Claus Algebra II
Hansen, Claus Trigonometry
Penor, Lori
Perham, Tom Algebra II
Peng, Yun-Feng
type schema
val db : schema.ServiceTypes.SimpleDataContextTypes.MyDatabase1
val student : System.Data.Linq.Table<schema.ServiceTypes.Student>
val data : int list = [1; 5; 7; 11; 18; 21]
type Nullable<'T
when 'T : (new : unit -> 'T) and 'T : struct and
'T :> System.ValueType> with
member Print : unit -> string
val num : int = 21
val student2 : schema.ServiceTypes.Student
val student3 : schema.ServiceTypes.Student
val student4 : schema.ServiceTypes.Student
val student5 : int = 1
val student6 : int = 8
val idList : int list = [1; 2; 5; 10]
val idQuery : seq<int>
val names : string [] = [|"a"; "b"; "c"|]
module Queries = begin
val query1 : System.Linq.IQueryable<string * System.Nullable<int>>
val query2 : System.Linq.IQueryable<string * System.Nullable<int>>
end
module Queries2 = begin
val query1 : System.Linq.IQueryable<string * System.Nullable<int>>
val query2 : System.Linq.IQueryable<string * System.Nullable<int>>
end