Analyzer rule
LC022: Nested Collection Materialization Inside Projection
EF Core LINQ performance analyzer and Roslyn analyzer for catching query issues at compile time.
LC022: Nested Collection Materialization Inside Projection
What it flags
Flags nested collection materialization inside projections because it can be expensive, provider-version sensitive, or better expressed with direct projection/split-query shaping.
Why it matters
LinqContraband reports this rule as an advisory performance signal. Modern EF Core can translate some correlated collection projections, so the diagnostic should prompt review rather than automatic removal.
Typical fix
Keep the projection provider-friendly, flatten the shape, use split queries where appropriate, or keep the nested materializer when a DTO contract requires a concrete collection.
The code fix is intentionally conservative. It only removes ToList() when the receiver type already matches the materialized type, such as a List<T> navigation projected as navigation.ToList(). It does not rewrite ToArray(), dictionary/set materializers, anonymous/object initializer members, or type-changing shapes such as stringValue.ToList().
Samples
See samples/LinqContraband.Sample/Samples/LC022_ToListInSelectProjection/ for a focused example.
The crime
var query = db.Customers
.Select(c => new
{
c.Id,
OrderIds = c.Orders.Select(o => o.Id).ToList()
});
A better shape
var query = db.Customers
.Select(c => new
{
c.Id,
OrderIds = c.Orders.Select(o => o.Id)
});
var results = await query.ToListAsync();