Invisible
No code review, no unit tests, no real versioning. The rule lives in the database and nobody quite knows what it does.
SQL Server → C#
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.
CREATE PROCEDURE dbo.OrdersByNote
@note varchar(20)
AS
SELECT Id, Total
FROM dbo.Orders
WHERE Note = @notenote = 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
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.
No code review, no unit tests, no real versioning. The rule lives in the database and nobody quite knows what it does.
Nobody knows who calls which procedure, so nobody dares to delete one, dead or alive.
Moving to the cloud or another database, splitting into services, going back to an ORM: they all hit the same wall.
Coding assistants cannot touch code they cannot see. With half the logic in the database, half the investment misses.
How it works
Four layers, each useful on its own. None of them changes your database; the proof runs on a disposable copy you mark as such.
Inventory
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.
Proof
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.
Migration
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.
Guard
Catches in CI a migrated procedure coming back, new ones being added, and code drifting from the database.
Demo
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.
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
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.
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.
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.
GETDATE() cannot match across two runs; it has to fall inside its own run. Identifiers drawn with NEWID() have to pair one to one.
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.
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
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.
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.
No. qlity runs in your environment. The proof runs on a disposable copy you mark as such, and never writes to production.
From production: SQL Server's Extended Events capture the real calls to the procedures you choose, and each one is run on both sides.
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
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.
What you write is used only to get back to you; it is not shared with third parties or added to any marketing list.