insta_pr_decline.md
· 2.3 KiB · Markdown
Исходник
# Instant PR decline reasons
## N+1 Queries
**Always** query all data you need before executing anything.
Incorrect:
```C#
foreach (var id in itemIds)
{
await _context.Items.FirstOrDefaultAsync(x => x.Id == id);
// Logic
await _context.SaveChangesAsync();
}
```
Correct:
```C#
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
```
## 2+ Queries updating/inserting without a transaction
If you don't know if you need it, you need it.
Incorrect
```C#
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
```
Correct
```C#
await using var transaction = await context.Database.BeginTransactionAsync();
try
{
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
await transaction.CommitAsync();
}
catch (Exception e)
{
await transaction.RollbackAsync();
// Handle exception or throw;
}
```
## 3+ Includes without AsSplitQuery() (without a select)
**Always** consider the query that will actually be executed. This will most often result in a [cartesian explosion](https://learn.microsoft.com/en-us/ef/core/querying/single-split-queries).
Incorrect
```C#
await _context.Users
.Include(u => u.Roles)
.Include(u => u.Events)
.Include(u => u.Installations)
.ThenInclude(i => i.Meters)
.AsAsyncEnumerable();
```
Correct:
```C#
await _context.Users
.Include(u => u.Roles)
.Include(u => u.Events)
.Include(u => u.Installations)
.ThenInclude(i => i.Meters)
.AsSplitQuery()
.AsAsyncEnumerable();
```
## Todos without issues
You **will** forget.
Incorrect
```C#
var theThing = getTheThing(); // TODO: Do the right thing!
```
Correct
```C#
var theThing = getTheThing(); // TODO: Do the right thing! (#8383)
```
## Not using async/await in EF Core
[EF core does not support parallel queries on the same context instance](https://learn.microsoft.com/en-us/ef/core/miscellaneous/async)
## Big/frequent queries without indexes
If you are executing a query a lot. It must have an index.
## Compiler warnings
No further explanation needed.
Instant PR decline reasons
N+1 Queries
Always query all data you need before executing anything.
Incorrect:
foreach (var id in itemIds)
{
await _context.Items.FirstOrDefaultAsync(x => x.Id == id);
// Logic
await _context.SaveChangesAsync();
}
Correct:
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
2+ Queries updating/inserting without a transaction
If you don't know if you need it, you need it.
Incorrect
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
Correct
await using var transaction = await context.Database.BeginTransactionAsync();
try
{
var items = await _context.Items.Where(x => itemIds.Contains(x.Id)).AsAsyncEnumerable();
await foreach (var item in items)
{
// Logic
}
await _context.SaveChangesAsync();
await transaction.CommitAsync();
}
catch (Exception e)
{
await transaction.RollbackAsync();
// Handle exception or throw;
}
3+ Includes without AsSplitQuery() (without a select)
Always consider the query that will actually be executed. This will most often result in a cartesian explosion.
Incorrect
await _context.Users
.Include(u => u.Roles)
.Include(u => u.Events)
.Include(u => u.Installations)
.ThenInclude(i => i.Meters)
.AsAsyncEnumerable();
Correct:
await _context.Users
.Include(u => u.Roles)
.Include(u => u.Events)
.Include(u => u.Installations)
.ThenInclude(i => i.Meters)
.AsSplitQuery()
.AsAsyncEnumerable();
Todos without issues
You will forget.
Incorrect
var theThing = getTheThing(); // TODO: Do the right thing!
Correct
var theThing = getTheThing(); // TODO: Do the right thing! (#8383)
Not using async/await in EF Core
EF core does not support parallel queries on the same context instance
Big/frequent queries without indexes
If you are executing a query a lot. It must have an index.
Compiler warnings
No further explanation needed.