Dext Fluent Query: Software Engineering and the Power of Community

The development of a modern framework like Dext doesn’t happen in a vacuum. It is the result of a constant dialogue between rigorous engineering and the real needs of those on the “front” developing complex applications.
Recently, Issue #117 of our official repository brought valuable discussions about the expressiveness and safety of SQL Joins in Fluent Query. What started as an enhancement request evolved into a deep analysis, resulting in the implementation of immediate improvements and the creation of the S19 specification, which outlines the future of Dext’s query engine.
In this article, we will explore how Fluent Query elevates Delphi code quality, the crucial role of our community in this process, and how we are transforming feedback into high-level technical specifications.
1. Quality Code: Readability that translates into Maintainability
Section titled “1. Quality Code: Readability that translates into Maintainability”The code we write is read far more often than it is written. Compare a traditional SQL string concatenation with Dext’s Fluent pattern:
The “Old Way” (Fragile and string-dependent):
Section titled “The “Old Way” (Fragile and string-dependent):”Query.SQL.Text := 'SELECT * FROM USERS WHERE AGE >= :MIN_AGE ORDER BY NAME ASC';Query.ParamByName('MIN_AGE').AsInteger := MinAge;Query.Open;The “Dext Way” (Robust and Expressive):
Section titled “The “Dext Way” (Robust and Expressive):”var u := Prototype.Entity<TUser>;var Adults := Context.Entities<TUser> .AsNoTracking .Where(u.Age >= 18) .OrderBy(u.Name.Asc) .Take(50) .ToList;Why is this superior quality?
- Real Type Safety (Peace of Mind): By using
u.Age, you bring the compiler to your side. If you rename theAgefield toBirthDatein theTUserclass tomorrow, Delphi won’t let you compile the project until all queries are fixed. Better yet: if you use a refactoring tool, it will update all references in your queries automatically—something impossible with SQL strings. Forget the “Field ‘AGE’ not found” errors that only appear when the client is using the system. - Intellisense and Productivity: You don’t need to memorize the database schema. When you type
u., the IDE shows exactly which fields are available, reducing cognitive load and eliminating typos. - Clear Intent: The chaining of methods (
.AsNoTracking,.Where,.OrderBy) transforms the code into living documentation. Any developer (including you in 6 months) understands the intent of the query in seconds. - Protection against SQL Injection: Since Fluent Query works with typed expressions, Dext handles parametrization natively and securely under the hood. You write Pascal code, and the framework takes care of SQL security.

2. The Testing Ecosystem: Way Beyond the Basics
Section titled “2. The Testing Ecosystem: Way Beyond the Basics”One of Dext’s greatest differentiators is that it’s not just an ORM; it’s accompanied by a complete Testing Framework (Sources\Testing), designed so that Fluent Query can be tested with absolute ease.
2.1 Decoupling and Native Mocking
Section titled “2.1 Decoupling and Native Mocking”Thanks to Dext’s interface-based architecture, you can “mock” your database effortlessly. Using Dext.Mocks, you can intercept calls and simulate complex returns:
var u := TUser.Prototype;var MockUsers := TList<TUser>.Create;// Fill simulated list...
Mock<IDextContext>.Setup .Returns(MockUsers) .When.Entities<TUser>;2.2 Fluent Assertions: Code that reads like English
Section titled “2.2 Fluent Assertions: Code that reads like English”Forget generic Assert.AreEqual. With Dext.Assertions, your checks are expressive and typed:
// Elegantly checking query resultsProducts.Should.HaveCount(3) .AndAlso.Contain(SomeProduct) .AndAlso.AllSatisfy(p.IsActive);2.3 Snapshot Testing: Goodbye Assertion Boilerplate
Section titled “2.3 Snapshot Testing: Goodbye Assertion Boilerplate”For queries that return complex objects or large JSON payloads, Dext offers Snapshot Testing. Instead of writing 50 manual assertions, you take a “snapshot” of the expected result:
// Compares query result with a JSON baseline saved on diskMatchSnapshot(ResultList, 'Sales_Report_January');2.4 Attribute-Based Testing
Section titled “2.4 Attribute-Based Testing”Dext uses a modern Runner inspired by xUnit/NUnit, allowing you to write tests without complex inheritance, using only metadata:
[Fixture],[Test],[Fact]to define scenarios.[TestCase(1, 2, 3)]for parameterized tests (Data-Driven).[Category('Integration')]to filter executions in CI/CD.

Advantage for your CI/CD: Since Dext’s testing ecosystem is native and integrated, your unit tests run in milliseconds, ensuring that changes in mapping or filter logic are validated instantly.
3. TFluentQuery: More than a Query, a Data Pipeline
Section titled “3. TFluentQuery: More than a Query, a Data Pipeline”To understand Dext’s power, you need to look under the hood of TFluentQuery<T>. Unlike traditional approaches that execute SQL immediately, Dext works with Deferred Execution.
3.1 Anatomy and Performance
Section titled “3.1 Anatomy and Performance”TFluentQuery<T> was implemented as a record. This means:
- Zero Heap Allocation: Creating a query doesn’t pressure the Memory Manager, as the state is kept on the stack.
- Automatic Lifecycle: As it is a value type (record), it is automatically released when it goes out of scope.
3.2 Deferred Execution
Section titled “3.2 Deferred Execution”The query is just a “blueprint”. You can compose your logic in multiple stages before triggering the actual execution.
var u := TUser.Prototype;var Query := Context.Entities<TUser>.AsNoTracking;
// Dynamic composition based on business rulesif OnlyActive then Query := Query.Where(u.IsActive = True);
if MinAge > 0 then Query := Query.Where(u.Age >= MinAge);
// SQL is only generated and executed HERE:var ResultList := Query.OrderBy(u.Name.Asc).ToList;3.3 Materialization: The Moment of Truth
Section titled “3.3 Materialization: The Moment of Truth”There are several ways to materialize your data, depending on the need:
Single Search (FirstOrDefault)
Section titled “Single Search (FirstOrDefault)”var u := TUser.Prototype;var User := Context.Entities<TUser> .Where(u.Email = 'contact@dext.com') .FirstOrDefault;
if User <> nil then ShowMessage('Welcome, ' + User.Name);Native Pagination (Paginate)
Section titled “Native Pagination (Paginate)”Ideal for Grids and APIs, executing COUNT and SELECT optimally.
var p := TProduct.Prototype;var PagedResult := Context.Entities<TProduct> .Where(p.Price > 100) .OrderBy(p.CreatedAt.Desc) .Paginate(1, 20); // Page 1, 20 records
WriteLn(Format('Showing %d of %d records', [PagedResult.Items.Count, PagedResult.TotalCount]));.ToList: For full lists in memory..Count / .Any: To check existence or volume without fetching records.
3.4 Streaming: Processing Millions with Constant Memory
Section titled “3.4 Streaming: Processing Millions with Constant Memory”For Big Data scenarios or massive exports, Dext offers GetStreamingEnumerator.
var LargeQuery := Context.Entities<TLog>().AsNoTracking;
// Streaming enumerator reuses internal object instances// keeping memory consumption low and stable throughout the iterationfor var Log in LargeQuery.GetStreamingEnumerator dobegin Process(Log);end;4. Complex Simplicity: The Engineering behind the DSL
Section titled “4. Complex Simplicity: The Engineering behind the DSL”For the developer experience to be absolutely simple, Dext’s internal engineering had to be viscerally complex.
Dext is the result of a healthy “fight” with language limits. We don’t accept the classic “you can’t do that in Delphi”. To create a DSL (Domain Specific Language) that is consistent across the framework—from Fluent Query to Collections, from the Specification Pattern to Expressions—it was necessary to orchestrate a technical symphony:
- Generics & Extended RTTI: To ensure powerful abstractions without losing typing.
- Managed Records & Operator Overloading: To create the fluid, “zero-allocation” syntax you see in queries.
- Class Functions & Interfaces: For an enterprise-level Dependency Injection and Decoupling architecture.
- Public Functions & Boldness: The creative and rigorous use of features introduced since Delphi 2009, pushed to the limit through hundreds of unit tests and constant self-criticism.
This consistency means that once you learn how to use Fluent Query, you already know how to filter a collection in memory or how to define a Specification for a Web API.

Imagine the power of defining a complex filter rule on your Frontend (or service layer) and passing it directly to the Backend, which translates it into optimized SQL securely. This avoids creating dozens of specific endpoints for each query variation, keeping your code clean, typed, and scalable. It’s a unique ecosystem, where internal complexity works silently to guarantee your productivity.
5. Real Performance and Dialect-Aware Architecture
Section titled “5. Real Performance and Dialect-Aware Architecture”It’s no use being beautiful if it’s not fast. The Fluent Query pipeline was designed for high performance:
- AsNoTracking: Drastically reduces memory overhead in read operations, bypassing the tracking lifecycle when you just need to list data.
- SQL Caching: Dext identifies repeat query signatures and reuses generated SQL, saving valuable CPU cycles.
- Column Qualification (Issue #117): We recently improved the SQL generator to automatically qualify all columns in JOIN scenarios. This eliminates the classic
ambiguous column name: Iderror that haunts those doing manual joins.
6. Community-Driven Evolution: Issue #117
Section titled “6. Community-Driven Evolution: Issue #117”Dext is not built in an ivory tower. Issue #117 is a perfect example. We received feedback about the need for more clarity and examples in SQL Joins.
What we delivered:
- SQL Generator Improvement: Now more robust against ambiguities.
- Simplified Overloads: Added easier ways to describe the JOIN condition.
- Reinforced Documentation: Real examples added to
Orm.EntityDemoand our official “Book”.
7. The Future: S19 and the Evolution of Fluent Query
Section titled “7. The Future: S19 and the Evolution of Fluent Query”Dext’s evolution doesn’t stop at V1. During the technical analysis of Issue #117, we identified opportunities to take the query experience to a new level. Thus was born the S19 specification, which defines the post-V1 roadmap for Fluent Query.
The goal of S19 is to consolidate Dext as the most expressive and performant ORM in the Delphi ecosystem. Among the planned new features are:
- Fully Typed DSL for JOIN: Elimination of strings in the ON clause, using pure Delphi expressions.
- Execution Clarity: Explicit APIs to distinguish database Joins from memory Joins (
JoinInMemory), avoiding accidental materializations. - Ergonomic Projections: New patterns like
SelectJoin<TResult>to map complex results without runtime reflection cost. - Diagnostics and Observability: Introduction of
TagWithfor query tracking andToQueryString()for immediate inspection of generated SQL and its parameters.
For architects who want to delve into technical details and zero-allocation performance guidelines for the next phase, the full specification is available at: S19-FluentQuery-Join-Evolution.md
8. The Versatility your Project Deserves
Section titled “8. The Versatility your Project Deserves”TFluentQuery<T> is not just for simple CRUDs. It is the foundation for:
- Complex Reports: High-performance projections and aggregations.
- Decoupled Business Logic: Repositories that return queries, allowing the UI layer to decide on pagination or sorting.
- Modern APIs: Native JSON integration and asynchronous materialization.
By mastering Fluent Query, you’re not just writing less code; you’re building Delphi applications prepared for the future.
Conclusion
Section titled “Conclusion”Dext’s Fluent Query transcends the concept of mere “Syntax Sugar”. It is a manifestation of rigorous software engineering, designed to inject type safety, brutal performance, and deterministic testability into the heart of modern Delphi applications.
We are moving Delphi from a past of “brittle strings” to a future where database querying is a first-class citizen, protected by the compiler and embraced by the community.
If you have the courage to abandon the “usual way” to embrace an architecture that scales with confidence, Dext is your next step.
📚 Learn More and Collaborate:
🚀 Want to collaborate? Check out Issue #117 and see how your participation can transform the Delphi ecosystem. The future of Dext is built by all of us.
Published by: Dext Framework Team Issue #117: Continuous Evolution via Community Feedback