Last active 2 weeks ago

Revision 4386b3240ec6a0858dab9345c183f2549e726578

insta_pr_decline.md Raw

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));
foreach (var item in items)
{
  // Logic
}
await _context.SaveChangesAsync();

2+ Queries updating/inserting queries 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));
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));
  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()

Always consider the query that will actually be executed.

Incorrect

await _context.Users
  .Include(u => u.Roles)
  .Include(u => u.Events)
  .Include(u => u.Installations)
  .ThenInclude(i => i.Meters)
  .ToListAsync();

Correct:

await _context.Users
  .Include(u => u.Roles)
  .Include(u => u.Events)
  .Include(u => u.Installations)
  .ThenInclude(i => i.Meters)
  .AsSplitQuery()
  .ToListAsync();

Todos without issues

You will forget.

var theThing = getTheThing(); // TODO: Do the right thing!
var theThing = getTheThing(); // TODO: Do the right thing! (#8383)

Big/frequent queries without indexes

If you are executing a query a lot. It must have an index.