![[Library] Avoiding combinatorial explosion in EF Core repositories](https://external-preview.redd.it/11Xnru_xGst126pJp0Fo3dPajEhiC8ll4mivHe9WHKE.png?width=1080&crop=smart&auto=webp&s=005dc3c7b4860e014238cc9c36bef59cd57337cd)
▲ 8 r/csharp
[Library] Avoiding combinatorial explosion in EF Core repositories
Hey guys!
I’ve been working on a library called QChain focused on reusable and composable DAL queries on top of LINQ and EF Core.
Main goal:
avoid duplicated joins, filters, projections, and repository method explosion in larger applications.
Instead of composing everything directly on IQueryable<T> with anonymous intermediate shapes, queries become reusable pipelines returning IQuery<T>.
Example:
public IQuery<(Account account, Order order)> ActiveEuropeanOrdersInLastMonth() =>
db.Accounts
.Join(db.Orders,
a => a.AccountId,
o => o.AccountId,
(a, o) => ValueTuple.Create(a, o))
.Where(x => x.account.IsActive().And(x.order.InLastMonth()));
Then later:
OrderDto[] orders = await unitOfWork.Query(db =>
db.AccountsRepository.ActiveEuropeanOrdersInLastMonth()
.Select(x => new OrderDto(x.order.OrderId, x.account.Email))
.Skip(index * size)
.Take(size))
.ToArrayAsync();
A big focus was preserving composability across joins/grouping while still translating correctly through EF Core.
Features:
- reusable predicates/specifications
- composable query pipelines
- tuple-based intermediate query shapes
- deferred execution
- EF Core integration
- escape hatch back to
IQueryable<T>viaAsQueryable()
Repo:
https://github.com/MihaiBratulescu/QChain
Would love feedback, especially from people dealing with large EF Core/repository/specification-heavy codebases.
u/ExpressionVsitor — 13 days ago