qlity

SQL Server → C#

Get your business logic out of the database. With proof.

qlity inventories your stored procedures, translates them into readable C#, and proves by running both that the new code returns the same rows and writes the same rows as the procedure did. Not a guess: a diff.

stored procedure
CREATE PROCEDURE dbo.OrdersByNote
    @note varchar(20)
AS
SELECT Id, Total
FROM dbo.Orders
WHERE Note = @note
generated code · EF Core
note = ProcedureParameters.AsVarChar(note, 20, 1252);

return await (
    from orders in db.Orders
    where (orders.Note != null && note != null
           && orders.Note == note)
    select new OrdersByNoteRow
    {
        Id = orders.Id,
        Total = orders.Total
    }).ToListAsync(cancellationToken);

equivalent — run against the procedure, a NULL parameter included

Problem

Part of your codebase is not in your code.

Thousands of stored procedures are normal in a decade-old .NET and SQL Server system. The business rules moved in there and cannot get out.

Invisible

No code review, no unit tests, no real versioning. The rule lives in the database and nobody quite knows what it does.

Undeletable

Nobody knows who calls which procedure, so nobody dares to delete one, dead or alive.

A wall

Moving to the cloud or another database, splitting into services, going back to an ORM: they all hit the same wall.

Blind to AI

Coding assistants cannot touch code they cannot see. With half the logic in the database, half the investment misses.

How it works

See it first, prove it, then move it.

Four layers, each useful on its own. None of them changes your database; the proof runs on a disposable copy you mark as such.

  1. 01working

    Inventory

    See what is where

    Every procedure, view, function and trigger; the call sites in your source; the dependency graph and the dead code. As a risk map you can share.

  2. 02working

    Proof

    Measure whether it is the same

    Runs the procedure and its replacement on the same calls from the same starting state, and compares what each returned and wrote, row by row.

  3. 03growing

    Migration

    Translate into readable code

    The body moves into code as LINQ over EF Core, or as SQL through Dapper, rendered from your templates in your code style. What it cannot translate, it says, with the reason.

  4. 04planned

    Guard

    Keep it from sliding back

    Catches in CI a migrated procedure coming back, new ones being added, and code drifting from the database.

Demo

Write a procedure, see what it becomes.

Write or paste your tables as CREATE TABLE and your procedure as CREATE PROCEDURE. The product's own engine translates it: what you write is sent to be translated only, never run, stored or logged.

Examples
T-SQL

Edit the script on the left or pick an example to translate.

The demo does not prove: proof needs the procedure and the new code run against a database. Shapes are read from the CREATE TABLE statements instead of a server; the collation is assumed Latin1.

Proof

Equivalent means indistinguishable, as far as the database can tell.

Not close: the same. Every rule has a written reason and none is loosened to make tests pass; it would rather raise a false alarm than hide a difference.

NULL as SQL has it

In T-SQL a comparison with NULL is neither true nor false. The generated LINQ writes every condition in that three-valued logic instead of leaving it to C#'s two values.

Parameters in the procedure's types

A procedure silently converts its input to its own types: varchar(4) cuts, datetime rounds. The generated code does the same, measured against the server.

Clocks and new identifiers

GETDATE() cannot match across two runs; it has to fall inside its own run. Identifiers drawn with NEWID() have to pair one to one.

Errors are behaviour

The same input has to be refused the same way. Where a procedure carries on after an error, so does its replacement; where it stops, so does the code.

Measured on a public schema

601 / 602

Dapper: equivalent

the one left is a known false alarm

575 / 575

EF Core: equivalent

303 of them writing, table state included

The 682 stored procedures of DNN Platform, each generated method against its own procedure, on a disposable copy. The numbers are reproducible with the measurement scripts in the repository.

FAQ

Frequently asked

Which databases and targets are supported?

Today, SQL Server to C#: EF Core, with the logic moved into LINQ, and Dapper, with the SQL kept in code. Output is rendered from templates and can follow your own repository layer and code style.

What about procedures it cannot translate?

It does not translate them, and says why: which construct, on which line. It never generates something close and moves on. The inventory shows that list up front, and the estimate follows from it.

Does our data leave our environment?

No. qlity runs in your environment. The proof runs on a disposable copy you mark as such, and never writes to production.

Where do the calls for the proof come from?

From production: SQL Server's Extended Events capture the real calls to the procedures you choose, and each one is run on both sides.

Do we have to move everything at once?

No. Each procedure is moved and proved on its own, and a gradual switch that keeps the old call signature is planned. Every step can be undone.

Contact

Let's look at your procedures together.

How many procedures you have, what you want to move, what is stopping you: a few lines is enough. We reply within one or two business days.

[email protected]

What you write is used only to get back to you; it is not shared with third parties or added to any marketing list.