TableCore

Codegen

From SQL query to MongoDB pipeline to C# code

A single query has three useful shapes: the SQL you think in, the pipeline MongoDB runs, and the driver code your application ships.

TableCore Team6 min read

One query, three shapes

A production query lives three lives. It starts as a thought in SQL, runs as a MongoDB command, and finally ships inside application code. Keeping the three in sync by hand is where bugs are born.

Take an unremarkable query:

SELECT displayName, active, score
FROM customers
WHERE active = true

Shape one: the MongoDB command

As a MongoDB operation this is not even an aggregation — a find with a projection is enough:

db.customers.find(
  { active: true },
  { displayName: 1, active: 1, score: 1 }
)

Knowing when a SQL query degrades into a full pipeline (a GROUP BY, a JOIN, a computed column) and when it stays a cheap find is half the craft.

Shape two: the C# driver code

The same query in the official C# driver wants a typed model and a typed filter:

public sealed class Customer
{
    [BsonId]
    public int Id { get; set; }

    [BsonElement("displayName")]
    public string? DisplayName { get; set; }

    [BsonElement("active")]
    public bool Active { get; set; }

    [BsonElement("score")]
    public int Score { get; set; }
}

var results = await database
    .GetCollection<Customer>("customers")
    .Find(c => c.Active)
    .ToListAsync();

Notice how much of this is derivable: the field names, the BSON attributes, the filter expression. None of it deserves to be typed by hand.

Shape three: LINQ

For teams that live in LINQ, the same operation reads almost like the SQL it came from:

var results = await collection.AsQueryable()
    .Where(c => c.Active)
    .Select(c => new { c.DisplayName, c.Active, c.Score })
    .ToListAsync();

Generate the boring parts

The transitions between these shapes are mechanical, and mechanical work belongs to tooling. TableCore renders the query you wrote as mongosh, C# driver code or C# LINQ — generated from the exact command the application would send, so what you paste into your codebase is what actually ran against your data. Which SQL gets that far is listed in SQL support.

Start with the browser-based SQL to MongoDB converter to see the database-side shape. For queries that need a pipeline, read how GROUP BY maps to $group and how a SQL JOIN maps to $lookup before generating the corresponding application code.

Try it yourself

Paste your SQL into TableCore and run it against MongoDB.

The desktop app converts your SQL into a real MongoDB query, shows the results as typed BSON and keeps both views in sync.

The download page reflects the current public release catalog. macOS and Linux are planned.