qlity

SQL Server → C#

Veritabanına gömülü iş mantığını koda taşıyın. Kanıtıyla.

qlity, stored procedure'larınızın envanterini çıkarır ve onları okunabilir C# koduna çevirir. Sonra ikisini de çalıştırıp yeni kodun aynı sonucu döndürdüğünü ve veritabanında aynı değişikliği yaptığını kanıtlar. Elinize tahmin değil, fark raporu geçer.

stored procedure
CREATE PROCEDURE dbo.OrdersByNote
    @note varchar(20)
AS
SELECT Id, Total
FROM dbo.Orders
WHERE Note = @note
üretilen kod · 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);

eşdeğer — prosedürle yan yana çalıştırıldı, NULL parametre de dahil

Problem

Kod tabanınızın bir kısmı kodda değil.

On yıllık bir .NET ve SQL Server sisteminde binlerce stored procedure olması gayet normal. İş kuralları zamanla oraya yerleşmiş, şimdi oradan çıkarılamıyor.

Görünmez

Code review yok, unit test yok, gerçek versiyonlama yok. Kural veritabanında yaşıyor ve kimse ne yaptığını tam bilmiyor.

Silinemez

Hangi prosedürü kimin çağırdığı belli değil. Hangisi kullanılıyor, hangisi ölü bilinmediği için kimse silmeye cesaret edemiyor.

Duvar

Buluta ya da başka bir veritabanına geçiş, servislere ayırma, ORM'e dönüş: hepsi aynı duvara çarpıyor.

Yapay zekâya kör

AI kod asistanları göremedikleri koda dokunamaz. İş mantığının yarısı veritabanındaysa, bu araçlara yapılan yatırımın yarısı boşa gidiyor.

Nasıl çalışır

Önce neyiniz olduğunu görün, sonra kanıtlayarak taşıyın.

Dört katman, her biri tek başına işe yarar. Hiçbiri veritabanınızı değiştirmez; kanıt yalnızca sizin “silinebilir” diye işaretlediğiniz bir kopyada çalışır.

  1. 01çalışıyor

    Envanter

    Neyin nerede olduğunu görün

    Tüm prosedürleri, view'ları, fonksiyonları ve trigger'ları; kaynak kodda nereden çağrıldıklarını, bağımlılık grafiğini ve ölü kodu çıkarır. Sonuç, ekiple paylaşabileceğiniz bir risk haritası.

  2. 02çalışıyor

    Kanıt

    Eskisiyle aynı mı, ölçün

    Prosedürü ve yerine geçen kodu aynı çağrılarla, aynı başlangıç durumundan çalıştırır; döndürdüklerini ve yazdıklarını satır satır karşılaştırır.

  3. 03genişliyor

    Taşıma

    Okunabilir koda çevirin

    Prosedürün içi EF Core için LINQ'e, Dapper için koddan çalışan SQL'e çevrilir. Çıktı sizin şablonlarınızla ve kod stilinizle üretilir. Çeviremediği yerde nedenini söyler.

  4. 04planlanıyor

    Koruma

    Geri kaymasın

    Taşınmış bir prosedür geri gelirse, yeni prosedür eklenirse ya da kodla veritabanı ayrışırsa bunu CI'da yakalar.

Demo

Bir prosedür yazın, ne üretildiğine bakın.

Tablolarınızı CREATE TABLE ile, prosedürünüzü CREATE PROCEDURE ile yazın ya da yapıştırın. Çeviriyi ürünün asıl motoru yapar. Yazdığınız kod yalnızca çeviri için sunucuya gider; çalıştırılmaz, saklanmaz, loglanmaz.

Örnekler
T-SQL

Çevirmek için soldaki script'i düzenleyin ya da bir örnek seçin.

Demo kanıt çalıştırmaz: kanıt, prosedürü ve yeni kodu bir veritabanında çalıştırmayı gerektirir. Şemalar sunucu yerine CREATE TABLE'lardan okunur; varsayılan collation Latin1.

Kanıt

Eşdeğer demek, veritabanı açısından ayırt edilemez demek.

Yaklaşık değil, birebir aynı. Her kuralın yazılı bir gerekçesi var ve hiçbiri testler geçsin diye gevşetilmez. Bir farkı gizlemektense yanlış alarm vermeyi tercih ederiz.

NULL, SQL'deki gibi

T-SQL'de NULL ile karşılaştırma ne doğru ne yanlıştır. Üretilen LINQ her koşulu bu üç değerli mantıkla yazar; C#'ın iki değerli mantığına bırakmaz.

Parametre, prosedürün tipinde

Prosedür gelen değeri sessizce kendi tipine çevirir: varchar(4) kırpar, datetime yuvarlar. Üretilen kod aynısını, sunucuyla ölçülerek yapar.

Saat ve yeni GUID'ler

GETDATE() iki çalıştırmada aynı değeri vermez; bu yüzden her değerin kendi çalıştırmasının aralığına düşüp düşmediğine bakılır. NEWID() ile üretilen GUID'ler iki taraf arasında birebir eşleştirilir.

Hata da davranıştır

Aynı girdiyi aynı şekilde reddetmek gerekir. Hatadan sonra devam eden prosedürün karşılığı da devam eder, duran da durur.

Açık bir şema üzerinde ölçüldü

633 / 633

Dapper: eşdeğer

veri yazan 329'unda tablo içeriği de karşılaştırıldı

609 / 610

EF Core: eşdeğer

tek fark belgeli: TOP (NULL) davranışı

DNN Platform'daki 682 stored procedure'dan Dapper 633'ünü, EF Core 610'unu üretti; kalanları nedenini söyleyerek reddetti, veritabanında olmayan bir tabloya giden 2'sini kapsam dışı saydı. Üretilen her metot, dolu ve tek kullanımlık bir kopyada, verilerden seçilen çağrılarla kendi prosedürüyle karşılaştırıldı. Rakamlar repodaki ölçüm script'leriyle yeniden üretilebilir.

SSS

Sık sorulanlar

Hangi veritabanları ve hedefler destekleniyor?

Bugün SQL Server'dan C#'a: EF Core (mantık LINQ'e taşınır) ve Dapper (SQL kodda kalır). Çıktı şablonlarla üretilir; kendi repository katmanınıza, kendi kod stilinize göre uyarlanabilir.

Çeviremediği prosedürler ne olacak?

Çevirmez ve nedenini söyler: hangi yapı, hangi satırda. Yakın bir şey üretip geçmek yok. Envanter bu listeyi baştan gösterir, efor tahmini buna göre yapılır.

Verilerimiz dışarı çıkıyor mu?

Hayır. qlity sizin ortamınızda çalışır. Kanıt, sizin işaretlediğiniz tek kullanımlık bir kopyada çalışır; üretim veritabanına yazmaz.

Kanıt için çağrılar nereden geliyor?

Üretimden: SQL Server'ın Extended Events'iyle, seçtiğiniz prosedürlere gelen gerçek çağrılar toplanır ve her biri iki tarafta da çalıştırılır.

Hepsini birden mi taşımamız gerekiyor?

Hayır. Her prosedür tek başına taşınır ve kanıtlanır; eski çağrı imzası korunarak kademeli geçiş planlanıyor. Her adım geri alınabilir.

İletişim

Prosedürlerinize birlikte bakalım.

Kaç prosedürünüz var, neyi taşımak istiyorsunuz, sizi ne durduruyor: birkaç satır yeter. 1-2 iş günü içinde dönüyoruz.

[email protected]

Yazdıklarınız yalnızca size dönmek için kullanılır; üçüncü taraflarla paylaşılmaz, pazarlama listesine eklenmez.