-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathProgram.cs
More file actions
133 lines (110 loc) · 3.71 KB
/
Copy pathProgram.cs
File metadata and controls
133 lines (110 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
BenchmarkRunner.Run<SplitQueryBenchmarks>();
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net10_0)]
[SimpleJob(RuntimeMoniker.Net11_0)]
public class SplitQueryBenchmarks
{
private SqliteConnection _connection = null!;
private DbContextOptions<BloggingContext> _options = null!;
[GlobalSetup]
public void Setup()
{
_connection = new SqliteConnection("Data Source=:memory:");
_connection.Open();
_options = new DbContextOptionsBuilder<BloggingContext>()
.UseSqlite(_connection)
.Options;
using var context = new BloggingContext(_options);
context.Database.EnsureCreated();
Seeder.Seed(context, blogCount: 5_000, postsPerBlog: 5);
}
[GlobalCleanup]
public void Cleanup() => _connection.Dispose();
[Benchmark]
public List<Blog> SplitQuery()
{
using var context = new BloggingContext(_options);
return BlogQuery(context).AsSplitQuery().ToList();
}
private static IQueryable<Blog> BlogQuery(BloggingContext context)
=> context.Blogs
.AsNoTracking()
.Include(b => b.Author)
.Include(b => b.Category)
.Include(b => b.Series)
.Include(b => b.Posts);
}
public class BloggingContext(DbContextOptions<BloggingContext> options) : DbContext(options)
{
public DbSet<Blog> Blogs => Set<Blog>();
}
public class Blog
{
public int Id { get; set; }
public string Name { get; set; } = "";
public int AuthorId { get; set; }
public Author Author { get; set; } = null!;
public int CategoryId { get; set; }
public Category Category { get; set; } = null!;
public int SeriesId { get; set; }
public Series Series { get; set; } = null!;
public List<Post> Posts { get; set; } = [];
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; } = "";
public int BlogId { get; set; }
public Blog Blog { get; set; } = null!;
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; } = "";
public List<Blog> Blogs { get; set; } = [];
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; } = "";
public List<Blog> Blogs { get; set; } = [];
}
public class Series
{
public int Id { get; set; }
public string Name { get; set; } = "";
public List<Blog> Blogs { get; set; } = [];
}
public static class Seeder
{
public static void Seed(BloggingContext context, int blogCount, int postsPerBlog)
{
var random = new Random(42);
var authors = Enumerable.Range(1, 500).Select(i => new Author { Name = $"Author {i}" }).ToArray();
var categories = Enumerable.Range(1, 100).Select(i => new Category { Name = $"Category {i}" }).ToArray();
var series = Enumerable.Range(1, 50).Select(i => new Series { Name = $"Series {i}" }).ToArray();
context.AddRange(authors);
context.AddRange(categories);
context.AddRange(series);
for (var i = 1; i <= blogCount; i++)
{
context.Add(new Blog
{
Name = $"Blog {i}",
Author = authors[random.Next(authors.Length)],
Category = categories[random.Next(categories.Length)],
Series = series[random.Next(series.Length)],
Posts = Enumerable.Range(1, postsPerBlog)
.Select(p => new Post { Title = $"Post {i}-{p}" })
.ToList(),
});
}
context.SaveChanges();
context.ChangeTracker.Clear();
}
}