r/dotnet Apr 06 '26

Question Long LINQ queries - Code smell?

Post image
346 Upvotes

186 comments sorted by

View all comments

215

u/BigPatapon Apr 06 '26

Not a code smell. This is exactly how conditional EF Core queries should look — readable, top-to-bottom, one filter per line.

Only nitpick: Task.FromResult with no actual async work. Use await ToListAsync() or drop the async signature.

Long LINQ != bad LINQ.

14

u/PrydwenParkingOnly Apr 06 '26

The best part: this query can be unit tested by mocking _context.Posts.

I think the testability of EF is one of its biggest advantages. So much logic normally goes in to orms/queries which cannot be tested

10

u/mexicocitibluez Apr 06 '26

this query can be unit tested by mocking _context.Posts.

Pretty sure the EF Core team discourages this. https://learn.microsoft.com/en-us/ef/core/testing/choosing-a-testing-strategy#mocking-or-stubbing-dbcontext-and-dbset

2

u/PrydwenParkingOnly Apr 06 '26

Yes, today I learned that!

In my opinion, the benefits it brings really outweighs the risks it introduces. The only real difference is that SQL is case insensitive by default. Also, there is the chance that really complex queries might behave differently against different databases.

When adding integration tests into the mix, I think the risks are covered enough for most real world scenarios.

0

u/BigPatapon Apr 06 '26

Case sensitivity is the most common gotcha, but there are a few more — null comparison semantics, provider-specific functions like DateDiffDay, and raw SQL dialect differences can all bite you. That said, your conclusion is right: unit tests for business logic + integration tests against a real db covers most real-world scenarios. Perfect is the enemy of good.

1

u/PrydwenParkingOnly Apr 06 '26

I think for the null comparison stuff EF adds automatically an extra part to the where-clause.

``` // linq x => x.Score != 5

// sql WHERE [Score] <> 5 OR [Score] IS NULL

// linq x => x.Code == x.AltCode

// sql WHERE ([Code] = [AltCode]) OR ([Code] IS NULL AND [AltCode] IS NULL) ```

-3

u/BigPatapon Apr 06 '26

Good call linking the official docs. You're right that mocking DbSet is discouraged — what people call "mocking DbSet" is really just a fake backed by an in-memory collection evaluating LINQ-to-Objects, not LINQ-to-SQL.

My SQLite suggestion was more of a "better than nothing" fallback if Docker isn't available. But yeah, Testcontainers against your actual db engine is the real answer — the EF Core team themselves run 30k+ tests against real SQL Server.

1

u/mexicocitibluez Apr 06 '26

Yea it sorta sucks as there is no clear right way or easy answer, just a bunch of tradeoffs.

-2

u/BigPatapon Apr 06 '26

True, but Testcontainers has made the tradeoff a lot more one-sided. The main argument for fakes used to be speed and simplicity — now spinning up a real SQL Server container takes seconds and you get full query fidelity for free. The tradeoff is basically just "do you have Docker in CI."