Skip to content

feat: translate first() and last() aggregates from LINQ - #73

Merged
sebastian-ederer merged 2 commits into
cmdscale:mainfrom
grzonu:feature/first-last-aggregates
Nov 4, 2026
Merged

sebastian-ederer merged 2 commits into
cmdscale:mainfrom
grzonu:feature/first-last-aggregates

Conversation

@grzonu

@grzonu grzonu commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Description

Adds EF.Functions.First(...) and EF.Functions.Last(...), which translate to the TimescaleDB first(value, time) and last(value, time) aggregates inside a GroupBy, alone or together with TimeBucket. The value and the ordering column are passed as a ValueTuple.Create(value, time) pair, the same idiom Npgsql uses for Correlation, so no custom expression type or SQL generator is needed: the translator is an IAggregateMethodCallTranslator registered next to the existing TimeBucket plugin (both in UseTimescaleDb() and AddEntityFrameworkTimescaleDb()). A Where on the group becomes FILTER (WHERE ...); Distinct() and OrderBy() inside the grouping are refused with an InvalidOperationException of their own, because the time argument already orders the rows (returning null instead let EF fail with an internal NullReferenceException on keyed entities). Docs are in docs/query-functions/first-last.md.

Related Issues

None.

Type of Change

  • Bug fix (non-breaking change addressing an issue)
  • New feature (non-breaking change adding functionality)
  • Refactoring
  • Documentation
  • CI / build / tooling
  • Breaking change (fix or feature causing existing functionality to change)

Test Plan

  • Unit tests added/updated: TimescaleDbFirstLastTranslatorTests
  • Integration tests added/updated (Testcontainers): FirstLastIntegrationTests (8 tests), plus SQL-baseline FirstLastQueryTests on the Community and Apache fixtures
  • Existing tests pass (dotnet test): Eftdb.Tests 2723 passed, 0 failed; Eftdb.FunctionalTests 95 passed, 0 failed

Checklist

  • Code follows the project's coding styles and guidelines
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • No new compiler warnings introduced
  • Public API changes have XML documentation

Adds EF.Functions.First and EF.Functions.Last so the TimescaleDB first(value, time)
and last(value, time) aggregates can be used in GroupBy queries, alone or together
with TimeBucket, without raw SQL.
@codecov

codecov Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Adds a translator test for a generic method of TimescaleDbFunctionsExtensions that is
neither First nor Last, and tests that calling EF.Functions.First and EF.Functions.Last
outside a query throws.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@sebastian-ederer
sebastian-ederer self-requested a review November 4, 2026 18:29

@sebastian-ederer sebastian-ederer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@sebastian-ederer

Copy link
Copy Markdown
Member

@grzonu Thanks for this PR! I had this feature on my bucket list and I can mark this as done now :)

@sebastian-ederer
sebastian-ederer merged commit 75e2256 into cmdscale:main Nov 4, 2026
2 checks passed
@grzonu
grzonu deleted the feature/first-last-aggregates branch November 4, 2026 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants