Выражения запросов (F#)
Выражения запросов позволяют применять с запросом источника данных и лежат данные в нужную форму.Выражения запросов обеспечивают поддержку LINQ в языке F#.
query { expression }
Заметки
Выражения запроса типа вычислительного выражения, аналогичный выражений последовательности.Точно так же, как указать последовательность, предоставляя код в выражении последовательности, задается набор данных, предоставляя код в выражении запроса.В выражении последовательности, ключевое слово yield определяет данные, которые нужно вернуть в рамках результирующую последовательность.В выражениях запроса, ключевое слово select выполняет ту же функцию.Помимо ключевого слова select, также F# поддерживает несколько операторов запроса, как в части SELECT выписки SQL.Ниже приведен пример простого выражения запроса вместе с кодом, который подключается к базе данных Northwind OData источника.
// Use the OData type provider to create types that can be used to access the Northwind database.
// Add References to FSharp.Data.TypeProviders and System.Data.Services.Client
open Microsoft.FSharp.Data.TypeProviders
type Northwind = ODataService<"http://services.odata.org/Northwind/Northwind.svc">
let db = Northwind.GetDataContext()
// A query expression.
let query1 = query { for customer in db.Customers do
select customer }
query1
|> Seq.iter (fun customer -> printfn "Company: %s Contact: %s" customer.CompanyName customer.ContactName)
В предыдущем примере кода, выражение запроса в фигурных скобках.Значение кода в выражении, возвращает каждый клиент в таблице customers в базе данных в результатах запроса.Выражения запросов возвращают тип, который реализует IQueryable<T> и IEnumerable<T>, и поэтому их можно выполнить с помощью Модуль Seq, как показано в примере.
Каждый тип вычислительного выражения строится из класса построителя.Класс построителя для вычислительного выражения запроса QueryBuilder.Дополнительные сведения см. в разделах Выражения вычисления (F#) и Класс Linq.QueryBuilder (F#).
Операторы запроса
Операторы запросов позволяют указать сведения о запросе, например для установки условия в наборе записей, который требуется возвратить или задать порядок сортировки результатов.Источник запроса должен поддерживать оператор запроса.При попытке использовать неподдерживаемый оператор запроса, создается исключение NotSupportedException.
Только выражения, которые можно преобразовать в SQL недопустимы в выражениях запроса.Например, если функция не допускаются в выражениях при использовании оператора запроса where.
Таблица отображает доступные операторы запроса.Кроме того, в разделе Table2, которое сравнивает запросы SQL и соответствующие выражения запроса F# далее в этом разделе.Некоторые операторы запроса не поддерживаются поставщиками приведенный типа.В частности, поставщик типа OData ограничен в операторах запроса, что он поддерживает из-за ограничений в OData.Дополнительные сведения см. в разделе Поставщик типов ODataService (F#).
Эта таблица имеет базу данных в следующей форме:
Схема базы данных
Код в таблицах приводится также имеет следующий код подключения базы данных.Проекты необходимо добавить ссылки на сборки System.Data, System.Data.Linq и FSharp.Data.TypeProviders.Код, создающий эту базу данных, в конце этого раздела.
open System
open Microsoft.FSharp.Data.TypeProviders
open System.Data.Linq.SqlClient
open System.Linq
open Microsoft.FSharp.Linq
type schema = SqlDataConnection<"Data Source=SERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;">
let db = schema.GetDataContext()
// Needed for some query operator examples:
let data = [ 1; 5; 7; 11; 18; 21]
Таблица.Операторы запроса
Оператор |
Описание |
contains |
Определяет, включается ли выбранные элементы указанный элемент.
|
count |
Возвращает число выбранных элементов.
|
last |
Выбирает последний элемент, выбранных на данный момент.
|
lastOrDefault |
Выбирает последний элемент этих выбранных рассмотрено, или значение по умолчанию, если элемент не найден.
|
exactlyOne |
Выделяет один определенный элемент, выбранный на данный момент.Если несколько элементов отсутствуют, вызывается исключение.
|
exactlyOneOrDefault |
Выделяет один определенный элемент, выбранных на данный момент, или значение по умолчанию, если этот элемент не найден.
|
headOrDefault |
Выбирает первый элемент, выбранных на данный момент, или значение по умолчанию, если последовательность не содержит элементов.
|
select |
Проекты каждое элементов, выбранных на данный момент.
|
where |
Выбирает элементы, основанный на указанном предикате.
|
minBy |
Выделяет значение для каждого элемента, выбранного на данный момент и возвращает минимальное результирующее значение.
|
maxBy |
Выделяет значение для каждого элемента, выбранного на данный момент и возвращает максимальное результирующее значение.
|
groupBy |
Группы элементов выбранные до сих пор в соответствии с указанным ключу селектор.
|
sortBy |
Сортирует элементы выбранные до сих пор в возрастающем порядке с заданным ключом.
|
sortByDescending |
Сортирует элементы выбранные до сих пор в порядке убывания заданного ключа.
|
thenBy |
Выполняет следующий порядок элементов, выбранных до сих пор в возрастающем порядке с заданным ключом.Этот оператор может использоваться только после sortBy, sortByDescending, thenBy или thenByDescending.
|
thenByDescending |
Выполняет следующий порядок элементов, выбранных до сих пор в порядке убывания заданного ключа.Этот оператор может использоваться только после sortBy, sortByDescending, thenBy или thenByDescending.
|
groupValBy |
Выделяет значение для каждого элемента, выбранного на данный момент и групп элементов заданного ключа.
|
join |
Коррелаты 2 набора выбранных значений на основе совпадающих ключей.Обратите внимание, что порядок ключей вокруг = данные для входа значительно выражение соединения.Во всем соединение, если линия разделена после символа ->, отступ не содержит отступов по крайней мере как при как ключевое слово for.
|
groupJoin |
Коррелаты 2 набора выбранных значений на основе совпадающих ключей и группах результаты.Обратите внимание, что порядок ключей вокруг = данные для входа значительно выражение соединения.
|
leftOuterJoin |
Коррелаты 2 набора выбранных значений на основе совпадающих ключей и группах результаты.Если какая-либо группа пуста, вместо нее используется группа с одним значением по умолчанию.Обратите внимание, что порядок ключей вокруг = данные для входа значительно выражение соединения.
|
sumByNullable |
Выделяет подобные значение для каждого элемента, выбранного на данный момент и возвращает сумму этих значений.Если какой-либо допускающий значение null элемент не имеет значения, он игнорируется.
|
minByNullable |
Выделяет подобные значение для каждого элемента, выбранного на данный момент и возвращает минимум этих значений.Если какой-либо допускающий значение null элемент не имеет значения, он игнорируется.
|
maxByNullable |
Выделяет подобные значение для каждого элемента, выбранного на данный момент и возвращает максимум этих значений.Если какой-либо допускающий значение null элемент не имеет значения, он игнорируется.
|
averageByNullable |
Выделяет подобные значение для каждого элемента, выбранного на данный момент и возвращает среднее значение этих значений.Если какой-либо допускающий значение null элемент не имеет значения, он игнорируется.
|
averageBy |
Выделяет значение для каждого элемента, выбранного на данный момент и возвращает среднее значение этих значений.
|
distinct |
Выделяет определенные элементы из выбранных элементов на данный момент.
|
exists |
Определяет, удовлетворяет ли любой элемент, выбранный на данный момент условие.
|
find |
Выбирает первый элемент, выбранный на данный момент, которые удовлетворяют указанному условию.
|
all |
Определяет, удовлетворяют ли все выбранные элементы до сих пор условие.
|
head |
Выбирает первый элемент из тех, на данный момент.
|
nth |
Распределяет элемент с указанным индексом для тех, на данный момент.
|
skip |
Пропускает указанное число элементов, выбранных до сих пор, и затем выбирает оставшиеся элементы.
|
skipWhile |
Пропускает элементы в последовательности, пока заданное условие является значение true, а затем выбирает оставшиеся элементы.
|
sumBy |
Выделяет значение для каждого элемента, выбранного на данный момент и возвращает сумму этих значений.
|
take |
Выделяет указанное число последовательных элементов от тех, на данный момент.
|
takeWhile |
Выбирает элементы из последовательности, пока заданное условие, а затем пропустить остальные элементы.
|
sortByNullable |
Сортирует элементы выбранные до сих пор в порядке возрастания заданного подобные ключом.
|
sortByNullableDescending |
Сортирует элементы выбранные до сих пор в порядке убывания заданного подобные ключом.
|
thenByNullable |
Выполняет следующий порядок элементов, выбранных до сих пор в порядке возрастания заданного подобные ключом.Этот оператор может использоваться только сразу после sortBy, sortByDescending, thenBy или thenByDescending, или их подобные вариантов.
|
thenByNullableDescending |
Выполняет следующий порядок элементов, выбранных до сих пор в порядке убывания заданного подобные ключом.Этот оператор может использоваться только сразу после sortBy, sortByDescending, thenBy или thenByDescending, или их подобные вариантов.
|
Сравнение выражений запросов Transact-SQL и F#
В следующей таблице показаны некоторые стандартные запросы Transact-SQL и их эквиваленты в языке F#.Код в этой таблице также имеет ту же базу данных, как в предыдущей таблице и этот же исходный код для настройки поставщика типа.
Таблица 2.Transact-SQL и выражения запроса F#
Следующий код можно использовать для создания базы данных примера этих примеров.
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);
Следующий код содержит пример кода, который отображается в этом разделе.
#if INTERACTIVE
#r "FSharp.Data.TypeProviders.dll"
#r "System.Data.dll"
#r "System.Data.Linq.dll"
#endif
open System
open Microsoft.FSharp.Data.TypeProviders
open System.Data.Linq.SqlClient
open System.Linq
[<Generate>]
type schema = SqlDataConnection<"Data Source=SERVER\INSTANCE;Initial Catalog=MyDatabase;Integrated Security=SSPI;">
let db = schema.GetDataContext()
let student = db.Student
let data = [1; 5; 7; 11; 18; 21]
open System
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 (for selection in db.CourseSelection ->
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 (for selection in db.CourseSelection ->
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 (for e in db.CourseSelection -> n.StudentID = e.StudentID)
count
}
|> printfn "%d"
printfn "\n Join with distinct."
query {
for student in db.Student do
join (for selection in db.CourseSelection ->
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 (for e in db.CourseSelection -> 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 (for courseSelection in db.CourseSelection ->
student.StudentID = courseSelection.StudentID) into g1
for courseSelection in g1.DefaultIfEmpty() do
leftOuterJoin (for course in db.Course ->
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.