-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Eliminate N+1 query in ServicoInterno #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
|
|
||
| # Ignore build artifacts | ||
| [Bb]in/ | ||
| [Oo]bj/ | ||
| BenchmarkDotNet.Artifacts/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <OutputType>Exe</OutputType> | ||
| <TargetFramework>net9.0</TargetFramework> | ||
| <ImplicitUsings>enable</ImplicitUsings> | ||
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="BenchmarkDotNet" Version="0.15.8" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.4" /> | ||
| <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.4" /> | ||
| <PackageReference Include="Moq" Version="4.20.72" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="..\RESTful API\RESTful API.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||
| using System; | ||||||
| using System.Linq; | ||||||
| using System.Threading.Tasks; | ||||||
| using BenchmarkDotNet.Attributes; | ||||||
| using BenchmarkDotNet.Running; | ||||||
| using Microsoft.EntityFrameworkCore; | ||||||
| using Microsoft.Extensions.Logging; | ||||||
| using Microsoft.Extensions.Configuration; | ||||||
| using Moq; | ||||||
| using RESTful_API.Models; | ||||||
| using RESTful_API.Service; | ||||||
| using RESTful_API.Interface; | ||||||
| using Microsoft.Data.Sqlite; | ||||||
|
Comment on lines
+1
to
+13
|
||||||
| using System.Data.Common; | ||||||
|
|
||||||
| [MemoryDiagnoser] | ||||||
| public class ServicoInternoBenchmark | ||||||
| { | ||||||
| private PdsContext _context = null!; | ||||||
| private DbConnection _connection = null!; | ||||||
|
|
||||||
| [GlobalSetup] | ||||||
| public void Setup() | ||||||
| { | ||||||
| _connection = new SqliteConnection("Filename=:memory:"); | ||||||
| _connection.Open(); | ||||||
|
|
||||||
| var options = new DbContextOptionsBuilder<PdsContext>() | ||||||
| .UseSqlite(_connection) | ||||||
| .Options; | ||||||
|
|
||||||
| _context = new PdsContext(options); | ||||||
| _context.Database.EnsureCreated(); | ||||||
|
|
||||||
| _context.Database.ExecuteSqlRaw("PRAGMA foreign_keys = OFF;"); | ||||||
|
|
||||||
| // Seed data | ||||||
| var login = new Login { Idlogin = 1, Email = "test@test.com" }; | ||||||
| _context.Logins.Add(login); | ||||||
|
|
||||||
| for (int i = 1; i <= 200; i++) | ||||||
| { | ||||||
| var cliente = new Cliente { Idcliente = i, NomeCliente = "Cliente " + i, LoginIdlogin = 1 }; | ||||||
| _context.Clientes.Add(cliente); | ||||||
|
|
||||||
| var aluguer1 = new Aluguer { | ||||||
| Idaluguer = i * 2 - 1, | ||||||
| ClienteIdcliente = i, | ||||||
| EstadoAluguer = "Alugado", | ||||||
| DataEntregaPrevista = DateTime.Now.AddDays(-1), | ||||||
| VeiculoIdveiculo = 1, | ||||||
| }; | ||||||
|
|
||||||
| _context.Aluguers.Add(aluguer1); | ||||||
| } | ||||||
|
Comment on lines
+33
to
+55
|
||||||
|
|
||||||
| var loginNav = new Login { Idlogin = 2, Email = "test2@test.com" }; | ||||||
| _context.Logins.Add(loginNav); | ||||||
|
Comment on lines
+57
to
+58
|
||||||
| var loginNav = new Login { Idlogin = 2, Email = "test2@test.com" }; | |
| _context.Logins.Add(loginNav); |
Copilot
AI
Apr 6, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both benchmarks, the loaded cliente value is assigned but never used. In the Optimized case, the JIT may be able to eliminate the navigation-property read entirely, which can skew results. Consider consuming a value from cliente (or using BenchmarkDotNet’s Consumer) so the work can’t be optimized away and both benchmarks measure comparable, real work.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,18 +36,18 @@ public async Task Executar() | |
| { | ||
| // Lógica da tarefa interna | ||
| var aluguers = await _context.Aluguers | ||
| .Include(a=>a.ClienteIdclienteNavigation) | ||
| .Where(a=>a.EstadoAluguer=="Aguarda Levantamento" && a.EstadoAluguer == "Alugado") | ||
| .Include(a => a.ClienteIdclienteNavigation) | ||
| .ThenInclude(c => c.LoginIdloginNavigation) | ||
| .Where(a => a.EstadoAluguer == "Aguarda Levantamento" || a.EstadoAluguer == "Alugado") | ||
| .ToListAsync(); | ||
|
Comment on lines
38
to
42
|
||
|
|
||
|
|
||
| foreach (var aluguer in aluguers) | ||
| { | ||
| if (aluguer.DataEntregaPrevista < DateTime.Now && aluguer.EstadoAluguer == "Alugado") | ||
| { | ||
| var cliente = await _context.Clientes | ||
| .Include(c => c.LoginIdloginNavigation) | ||
| .FirstOrDefaultAsync(c => c.Idcliente == aluguer.ClienteIdcliente); if (cliente != null ) | ||
| var cliente = aluguer.ClienteIdclienteNavigation; | ||
| if (cliente != null) | ||
| { | ||
| var email = cliente.LoginIdloginNavigation.Email; | ||
| var assunto = "Notificação de Devolução do Veiculo"; | ||
|
|
@@ -69,9 +69,7 @@ public async Task Executar() | |
|
|
||
| if (aluguer.DataLevantamento < DateTime.Now && aluguer.EstadoAluguer == "Aguarda Levantamento") | ||
| { | ||
| var cliente = await _context.Clientes | ||
| .Include(c => c.LoginIdloginNavigation) | ||
| .FirstOrDefaultAsync(c => c.Idcliente == aluguer.ClienteIdcliente); | ||
| var cliente = aluguer.ClienteIdclienteNavigation; | ||
|
|
||
| if (cliente != null) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This project references packages that don't appear to be used by the benchmark code (
Microsoft.EntityFrameworkCore.InMemory,Moq). Keeping only the required PackageReferences reduces restore/build time and dependency footprint.