Skip to content

Commit d1680c7

Browse files
CopilotT-Gro
andcommitted
Replace in-memory examples with Entity Framework Core as requested
Co-authored-by: T-Gro <[email protected]>
1 parent 6ad8a82 commit d1680c7

File tree

4 files changed

+102
-61
lines changed

4 files changed

+102
-61
lines changed

docs/fsharp/language-reference/query-expressions.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ query { expression }
1616

1717
## Remarks
1818

19-
Query expressions are a type of computation expression similar to sequence expressions. Just as you specify a sequence by providing code in a sequence expression, you specify a set of data by providing code in a query expression. In a sequence expression, the `yield` keyword identifies data to be returned as part of the resulting sequence. In query expressions, the `select` keyword performs the same function. In addition to the `select` keyword, F# also supports a number of query operators that are much like the parts of a SQL SELECT statement. Here is an example of a simple query expression using in-memory data.
19+
Query expressions are a type of computation expression similar to sequence expressions. Just as you specify a sequence by providing code in a sequence expression, you specify a set of data by providing code in a query expression. In a sequence expression, the `yield` keyword identifies data to be returned as part of the resulting sequence. In query expressions, the `select` keyword performs the same function. In addition to the `select` keyword, F# also supports a number of query operators that are much like the parts of a SQL SELECT statement. Here is an example of a simple query expression using Entity Framework Core to query a database.
2020

2121
:::code language="fsharp" source="~/samples/snippets/fsharp/query-expressions/snippet1.fs":::
2222

@@ -36,7 +36,7 @@ This table assumes a database in the following form:
3636

3737
![Diagram that shows a sample database.](./media/query-expressions/student-course-database.png)
3838

39-
The code in the tables that follow also assumes the following database connection code. Projects should add references to System.Linq. The code that creates this database is included at the end of this topic.
39+
The code in the tables that follow also assumes the following database connection code using Entity Framework Core. Projects should add package references to `Microsoft.EntityFrameworkCore` and `Microsoft.EntityFrameworkCore.InMemory` (or another EF Core provider for production scenarios). This example uses the in-memory database provider for demonstration purposes, but the same query syntax works with any EF Core provider (SQL Server, PostgreSQL, etc.).
4040

4141
:::code language="fsharp" source="~/samples/snippets/fsharp/query-expressions/snippet2.fs":::
4242

samples/snippets/fsharp/fssamples.fsproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
</ItemGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="FSharp.Data" Version="6.4.0" />
18+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
19+
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.0" />
1920
</ItemGroup>
2021

2122
</Project>

samples/snippets/fsharp/query-expressions/snippet1.fs

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,42 @@
1-
// Modern F# query expression example using in-memory data
1+
// F# query expression example using Entity Framework Core
22
open System
33
open System.Linq
4+
open Microsoft.EntityFrameworkCore
45

5-
// Simple data structures
6+
// Entity type
7+
[<CLIMutable>]
68
type Customer = {
79
CustomerID: int
810
CompanyName: string
911
ContactName: string
1012
}
1113

12-
// Sample data
13-
let customers = [
14-
{ CustomerID = 1; CompanyName = "Alfreds Futterkiste"; ContactName = "Maria Anders" }
15-
{ CustomerID = 2; CompanyName = "Ana Trujillo Emparedados y helados"; ContactName = "Ana Trujillo" }
16-
{ CustomerID = 3; CompanyName = "Antonio Moreno Taquería"; ContactName = "Antonio Moreno" }
17-
]
14+
// Database context
15+
type NorthwindContext() =
16+
inherit DbContext()
17+
18+
[<DefaultValue>]
19+
val mutable private customers: DbSet<Customer>
20+
member this.Customers with get() = this.customers and set v = this.customers <- v
21+
22+
override _.OnConfiguring(optionsBuilder: DbContextOptionsBuilder) =
23+
optionsBuilder.UseInMemoryDatabase("NorthwindDatabase") |> ignore
1824

19-
let db = customers.AsQueryable()
25+
// Create and seed database
26+
let db =
27+
let context = new NorthwindContext()
28+
context.Customers.AddRange([|
29+
{ CustomerID = 1; CompanyName = "Alfreds Futterkiste"; ContactName = "Maria Anders" }
30+
{ CustomerID = 2; CompanyName = "Ana Trujillo Emparedados y helados"; ContactName = "Ana Trujillo" }
31+
{ CustomerID = 3; CompanyName = "Antonio Moreno Taquería"; ContactName = "Antonio Moreno" }
32+
|]) |> ignore
33+
context.SaveChanges() |> ignore
34+
context
2035

2136
// A query expression
2237
let query1 =
2338
query {
24-
for customer in db do
39+
for customer in db.Customers do
2540
select customer
2641
}
2742

Lines changed: 73 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,97 @@
1-
// Database setup example for query expressions
1+
// Database setup example for query expressions using Entity Framework Core
22
open System
33
open System.Linq
4+
open Microsoft.EntityFrameworkCore
45

5-
// Define simple data types to represent our sample database
6+
// Define entity types that map to database tables
7+
[<CLIMutable>]
68
type Student = {
79
StudentID: int
810
Name: string
9-
Age: int option
11+
Age: Nullable<int>
1012
}
1113

14+
[<CLIMutable>]
1215
type Course = {
1316
CourseID: int
1417
CourseName: string
1518
}
1619

20+
[<CLIMutable>]
1721
type CourseSelection = {
1822
ID: int
1923
StudentID: int
2024
CourseID: int
2125
}
2226

23-
// Sample data
24-
let students = [
25-
{ StudentID = 1; Name = "Abercrombie, Kim"; Age = Some 10 }
26-
{ StudentID = 2; Name = "Abolrous, Hazen"; Age = Some 14 }
27-
{ StudentID = 3; Name = "Hance, Jim"; Age = Some 12 }
28-
{ StudentID = 4; Name = "Adams, Terry"; Age = Some 12 }
29-
{ StudentID = 5; Name = "Hansen, Claus"; Age = Some 11 }
30-
{ StudentID = 6; Name = "Penor, Lori"; Age = Some 13 }
31-
{ StudentID = 7; Name = "Perham, Tom"; Age = Some 12 }
32-
{ StudentID = 8; Name = "Peng, Yun-Feng"; Age = None }
33-
]
27+
// Define the database context using Entity Framework Core
28+
type SchoolContext() =
29+
inherit DbContext()
30+
31+
[<DefaultValue>]
32+
val mutable private student: DbSet<Student>
33+
member this.Student with get() = this.student and set v = this.student <- v
34+
35+
[<DefaultValue>]
36+
val mutable private course: DbSet<Course>
37+
member this.Course with get() = this.course and set v = this.course <- v
38+
39+
[<DefaultValue>]
40+
val mutable private courseSelection: DbSet<CourseSelection>
41+
member this.CourseSelection with get() = this.courseSelection and set v = this.courseSelection <- v
42+
43+
override _.OnConfiguring(optionsBuilder: DbContextOptionsBuilder) =
44+
optionsBuilder.UseInMemoryDatabase("SchoolDatabase") |> ignore
3445

35-
let courses = [
36-
{ CourseID = 1; CourseName = "Algebra I" }
37-
{ CourseID = 2; CourseName = "Trigonometry" }
38-
{ CourseID = 3; CourseName = "Algebra II" }
39-
{ CourseID = 4; CourseName = "History" }
40-
{ CourseID = 5; CourseName = "English" }
41-
{ CourseID = 6; CourseName = "French" }
42-
{ CourseID = 7; CourseName = "Chinese" }
43-
]
46+
// Create and seed the database
47+
let createAndSeedDatabase() =
48+
let context = new SchoolContext()
49+
50+
// Seed data
51+
context.Student.AddRange([|
52+
{ StudentID = 1; Name = "Abercrombie, Kim"; Age = Nullable(10) }
53+
{ StudentID = 2; Name = "Abolrous, Hazen"; Age = Nullable(14) }
54+
{ StudentID = 3; Name = "Hance, Jim"; Age = Nullable(12) }
55+
{ StudentID = 4; Name = "Adams, Terry"; Age = Nullable(12) }
56+
{ StudentID = 5; Name = "Hansen, Claus"; Age = Nullable(11) }
57+
{ StudentID = 6; Name = "Penor, Lori"; Age = Nullable(13) }
58+
{ StudentID = 7; Name = "Perham, Tom"; Age = Nullable(12) }
59+
{ StudentID = 8; Name = "Peng, Yun-Feng"; Age = Nullable() }
60+
|]) |> ignore
61+
62+
context.Course.AddRange([|
63+
{ CourseID = 1; CourseName = "Algebra I" }
64+
{ CourseID = 2; CourseName = "Trigonometry" }
65+
{ CourseID = 3; CourseName = "Algebra II" }
66+
{ CourseID = 4; CourseName = "History" }
67+
{ CourseID = 5; CourseName = "English" }
68+
{ CourseID = 6; CourseName = "French" }
69+
{ CourseID = 7; CourseName = "Chinese" }
70+
|]) |> ignore
71+
72+
context.CourseSelection.AddRange([|
73+
{ ID = 1; StudentID = 1; CourseID = 2 }
74+
{ ID = 2; StudentID = 1; CourseID = 3 }
75+
{ ID = 3; StudentID = 1; CourseID = 5 }
76+
{ ID = 4; StudentID = 2; CourseID = 2 }
77+
{ ID = 5; StudentID = 2; CourseID = 5 }
78+
{ ID = 6; StudentID = 2; CourseID = 6 }
79+
{ ID = 7; StudentID = 2; CourseID = 3 }
80+
{ ID = 8; StudentID = 3; CourseID = 2 }
81+
{ ID = 9; StudentID = 3; CourseID = 1 }
82+
{ ID = 10; StudentID = 4; CourseID = 2 }
83+
{ ID = 11; StudentID = 4; CourseID = 5 }
84+
{ ID = 12; StudentID = 4; CourseID = 2 }
85+
{ ID = 13; StudentID = 5; CourseID = 3 }
86+
{ ID = 14; StudentID = 5; CourseID = 2 }
87+
{ ID = 15; StudentID = 7; CourseID = 3 }
88+
|]) |> ignore
89+
90+
context.SaveChanges() |> ignore
91+
context
4492

45-
let courseSelections = [
46-
{ ID = 1; StudentID = 1; CourseID = 2 }
47-
{ ID = 2; StudentID = 1; CourseID = 3 }
48-
{ ID = 3; StudentID = 1; CourseID = 5 }
49-
{ ID = 4; StudentID = 2; CourseID = 2 }
50-
{ ID = 5; StudentID = 2; CourseID = 5 }
51-
{ ID = 6; StudentID = 2; CourseID = 6 }
52-
{ ID = 7; StudentID = 2; CourseID = 3 }
53-
{ ID = 8; StudentID = 3; CourseID = 2 }
54-
{ ID = 9; StudentID = 3; CourseID = 1 }
55-
{ ID = 10; StudentID = 4; CourseID = 2 }
56-
{ ID = 11; StudentID = 4; CourseID = 5 }
57-
{ ID = 12; StudentID = 4; CourseID = 2 }
58-
{ ID = 13; StudentID = 5; CourseID = 3 }
59-
{ ID = 14; StudentID = 5; CourseID = 2 }
60-
{ ID = 15; StudentID = 7; CourseID = 3 }
61-
]
62-
63-
// Create a db object that mimics a database context
64-
type DataContext() =
65-
member _.Student = students.AsQueryable()
66-
member _.Course = courses.AsQueryable()
67-
member _.CourseSelection = courseSelections.AsQueryable()
68-
69-
let db = DataContext()
93+
// Create the database context
94+
let db = createAndSeedDatabase()
7095

7196
// Needed for some query operator examples:
7297
let data = [ 1; 5; 7; 11; 18; 21]

0 commit comments

Comments
 (0)