Skip to content

Commit 522365e

Browse files
Filtered Include: retarget net10.0, EF Core 10.0.11, add Assignment entity (#2176)
Retargets both projects from net6.0 to net10.0 and lifts the four EF Core packages from 6.0.8 to 10.0.11, with the test packages moved to Microsoft.NET.Test.Sdk 18.9.0, xunit 2.9.3, xunit.runner.visualstudio 4.0.0 and coverlet.collector 10.0.1. Adds TrustServerCertificate=True to the connection string. EF Core 10 loads Microsoft.Data.SqlClient 6.1.6, where Encrypt defaults to true and TrustServerCertificate to false, so without it every test fails on the certificate chain against a local SQL Server. Adds an Assignment entity and an Assignments collection on Student, with the migration and a seeding change, so the sample can demonstrate the documented multi-level ThenInclude form after a filtered Include. New query methods: GoodFilteringOnMultipleIncludeWithThenInclude, FilteredIncludeWithSortingAndPaging, FilteredIncludeWithoutMatchingStudents and ExplicitLoadingWithFilter, each with a test. Renames the shadowed lambda parameters in FilteringInsideIncludeAndSelectMethod to c and s. Adds the folder to .github/ci-skip-folders.txt beside its three EF Core siblings: the ten existing facts and the four new ones need a live SQL Server, which the runner does not have. Verified locally on SQL Server LocalDB: 14 of 14 passed on net10.0, SDK 10.0.302.
1 parent 3362dca commit 522365e

10 files changed

Lines changed: 334 additions & 18 deletions

File tree

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/FilteringResultsInsideInclude.csproj‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
12-
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.8">
11+
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.11" />
12+
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.11">
1313
<PrivateAssets>all</PrivateAssets>
1414
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1515
</PackageReference>
16-
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.8" />
17-
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.8">
16+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.11" />
17+
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.11">
1818
<PrivateAssets>all</PrivateAssets>
1919
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2020
</PackageReference>

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/Migrations/20260907111628_AddAssignment.Designer.cs‎

Lines changed: 122 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using Microsoft.EntityFrameworkCore.Migrations;
2+
3+
#nullable disable
4+
5+
namespace FilteringResultsInsideInclude.Migrations
6+
{
7+
/// <inheritdoc />
8+
public partial class AddAssignment : Migration
9+
{
10+
/// <inheritdoc />
11+
protected override void Up(MigrationBuilder migrationBuilder)
12+
{
13+
migrationBuilder.CreateTable(
14+
name: "Assignments",
15+
columns: table => new
16+
{
17+
Id = table.Column<int>(type: "int", nullable: false)
18+
.Annotation("SqlServer:Identity", "1, 1"),
19+
Title = table.Column<string>(type: "nvarchar(max)", nullable: true),
20+
StudentId = table.Column<int>(type: "int", nullable: false)
21+
},
22+
constraints: table =>
23+
{
24+
table.PrimaryKey("PK_Assignments", x => x.Id);
25+
table.ForeignKey(
26+
name: "FK_Assignments_Students_StudentId",
27+
column: x => x.StudentId,
28+
principalTable: "Students",
29+
principalColumn: "Id",
30+
onDelete: ReferentialAction.Cascade);
31+
});
32+
33+
migrationBuilder.CreateIndex(
34+
name: "IX_Assignments_StudentId",
35+
table: "Assignments",
36+
column: "StudentId");
37+
}
38+
39+
/// <inheritdoc />
40+
protected override void Down(MigrationBuilder migrationBuilder)
41+
{
42+
migrationBuilder.DropTable(
43+
name: "Assignments");
44+
}
45+
}
46+
}

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/Migrations/AppDbContextModelSnapshot.cs‎

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,39 @@ protected override void BuildModel(ModelBuilder modelBuilder)
1616
{
1717
#pragma warning disable 612, 618
1818
modelBuilder
19-
.HasAnnotation("ProductVersion", "6.0.8")
19+
.HasAnnotation("ProductVersion", "10.0.11")
2020
.HasAnnotation("Relational:MaxIdentifierLength", 128);
2121

22-
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
22+
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
23+
24+
modelBuilder.Entity("FilteringResultsInsideInclude.Models.Assignment", b =>
25+
{
26+
b.Property<int>("Id")
27+
.ValueGeneratedOnAdd()
28+
.HasColumnType("int");
29+
30+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
31+
32+
b.Property<int>("StudentId")
33+
.HasColumnType("int");
34+
35+
b.Property<string>("Title")
36+
.HasColumnType("nvarchar(max)");
37+
38+
b.HasKey("Id");
39+
40+
b.HasIndex("StudentId");
41+
42+
b.ToTable("Assignments");
43+
});
2344

2445
modelBuilder.Entity("FilteringResultsInsideInclude.Models.Course", b =>
2546
{
2647
b.Property<int>("Id")
2748
.ValueGeneratedOnAdd()
2849
.HasColumnType("int");
2950

30-
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
51+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
3152

3253
b.Property<string>("Title")
3354
.HasColumnType("nvarchar(max)");
@@ -43,7 +64,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
4364
.ValueGeneratedOnAdd()
4465
.HasColumnType("int");
4566

46-
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"), 1L, 1);
67+
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
4768

4869
b.Property<int>("CourseId")
4970
.HasColumnType("int");
@@ -61,6 +82,17 @@ protected override void BuildModel(ModelBuilder modelBuilder)
6182
b.ToTable("Students");
6283
});
6384

85+
modelBuilder.Entity("FilteringResultsInsideInclude.Models.Assignment", b =>
86+
{
87+
b.HasOne("FilteringResultsInsideInclude.Models.Student", "Student")
88+
.WithMany("Assignments")
89+
.HasForeignKey("StudentId")
90+
.OnDelete(DeleteBehavior.Cascade)
91+
.IsRequired();
92+
93+
b.Navigation("Student");
94+
});
95+
6496
modelBuilder.Entity("FilteringResultsInsideInclude.Models.Student", b =>
6597
{
6698
b.HasOne("FilteringResultsInsideInclude.Models.Course", "Course")
@@ -76,6 +108,11 @@ protected override void BuildModel(ModelBuilder modelBuilder)
76108
{
77109
b.Navigation("Students");
78110
});
111+
112+
modelBuilder.Entity("FilteringResultsInsideInclude.Models.Student", b =>
113+
{
114+
b.Navigation("Assignments");
115+
});
79116
#pragma warning restore 612, 618
80117
}
81118
}

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/Models/AppDbContext.cs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ public class AppDbContext : DbContext
66
{
77
public DbSet<Student>? Students { get; set; }
88
public DbSet<Course>? Courses { get; set; }
9+
public DbSet<Assignment>? Assignments { get; set; }
910

1011
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
1112
{
12-
optionsBuilder.UseSqlServer(@"Server=.;Database=AppDB;Trusted_Connection=True;");
13+
optionsBuilder.UseSqlServer(@"Server=.;Database=AppDB;Trusted_Connection=True;TrustServerCertificate=True;");
1314
}
1415
}
1516
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace FilteringResultsInsideInclude.Models
2+
{
3+
public class Assignment
4+
{
5+
public int Id { get; set; }
6+
public string? Title { get; set; }
7+
8+
public int StudentId { get; set; }
9+
public Student? Student { get; set; }
10+
}
11+
}

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/Models/Student.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ public class Student
88

99
public int CourseId { get; set; }
1010
public Course? Course { get; set; }
11+
12+
public ICollection<Assignment>? Assignments { get; set; }
1113
}
1214
}

‎dotnet-efcore/FilteringResultsInsideTheIncludeMethodInEFCore/FilteringResultsInsideInclude/Queries.cs‎

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ public class Queries
77
{
88
public const int CourseCount = 10;
99
public const int StudentCountPerCourse = 100;
10-
10+
public const int AssignmentCountPerStudent = 2;
11+
1112
public static async Task SeedData(AppDbContext context)
1213
{
1314
if (!context.Courses!.Any())
@@ -18,7 +19,11 @@ public static async Task SeedData(AppDbContext context)
1819
Students = Enumerable.Range(1, StudentCountPerCourse).Select(j => new Student()
1920
{
2021
Name = $"Student {10 * i + j}",
21-
Mark = j
22+
Mark = j,
23+
Assignments = Enumerable.Range(1, AssignmentCountPerStudent).Select(k => new Assignment
24+
{
25+
Title = $"Assignment {k}"
26+
}).ToList()
2227
}).ToList()
2328
}).ToList();
2429

@@ -55,6 +60,18 @@ public static List<Course> GoodFilteringOnMultipleInclude(AppDbContext context)
5560
return goodQuery;
5661
}
5762

63+
public static List<Course> GoodFilteringOnMultipleIncludeWithThenInclude(AppDbContext context)
64+
{
65+
var goodQuery = context.Courses!
66+
.Include(c => c.Students!.Where(s => s.Mark > 50))
67+
.ThenInclude(s => s.Assignments)
68+
.Include(c => c.Students!)
69+
.ThenInclude(s => s.Assignments)
70+
.ToList();
71+
72+
return goodQuery;
73+
}
74+
5875
public static List<Course> BadFilteringOnMultipleInclude(AppDbContext context)
5976
{
6077
var badQuery = context.Courses!
@@ -98,7 +115,7 @@ public static List<Course> FilteredIncludeWithTrackingQueries2(AppDbContext cont
98115
public static List<Course> FilteringInsideIncludeAndSelectMethod(AppDbContext context)
99116
{
100117
var courses = context.Courses!
101-
.Include(x => x.Students!.Where(x => x.Mark > 50))
118+
.Include(c => c.Students!.Where(s => s.Mark > 50))
102119
.Select(c => new Course
103120
{
104121
Id = c.Id,
@@ -122,5 +139,37 @@ public static List<Course> FilteringInsideSelectMethodWithoutInclude(AppDbContex
122139
return courses;
123140
}
124141

142+
public static List<Course> FilteredIncludeWithSortingAndPaging(AppDbContext context)
143+
{
144+
var topStudents = context.Courses!
145+
.Include(c => c.Students!
146+
.Where(s => s.Mark > 50)
147+
.OrderByDescending(s => s.Mark)
148+
.Take(3))
149+
.ToList();
150+
151+
return topStudents;
152+
}
153+
154+
public static List<Course> FilteredIncludeWithoutMatchingStudents(AppDbContext context)
155+
{
156+
var courses = context.Courses!
157+
.Include(c => c.Students!.Where(s => s.Mark > StudentCountPerCourse))
158+
.ToList();
159+
160+
return courses;
161+
}
162+
163+
public static List<Student> ExplicitLoadingWithFilter(AppDbContext context, Course course)
164+
{
165+
var students = context.Entry(course)
166+
.Collection(c => c.Students!)
167+
.Query()
168+
.Where(s => s.Mark > 50)
169+
.ToList();
170+
171+
return students;
172+
}
173+
125174
}
126175
}

0 commit comments

Comments
 (0)