← Tüm yazılar

Şemadan DTO ve proje dosyası üretmek

Şemadan kod üretirken en tehlikeli çıktı, derlenmeyen çıktıdır. Aynı alanları elle tekrar yazmak yerine küçük bir üretici kullanıyorum; fakat üretilecek ad ve tipleri önce sınırlıyorum.

t.Turgay
Şemadan DTO ve proje dosyası üretmek

Aynı kolonları DTO, model ve servis parametresi olarak tekrar yazınca hata genellikle en sıkıcı yerde çıkar: bir ad değişir, diğer dosya unutulur. Şemadan üretim bu tekrarı azaltır. Fakat veritabanındaki bir kolon adını doğrudan C# metnine yerleştirmek, üreticiyi güvenilir yapmaz. Arşivimdeki masaüstü üretim aracında model ve başlangıç dosyalarını hazırlayan şablonlar var; burada o yaklaşımın en küçük, denetlenebilir parçasını ele alıyorum.

Önce üretilecek dili sınırlamak

Girdimiz Id/int ve Title/string çiftleri. Çıktı public sealed record ItemDto(int Id, string Title); olacak. Örneği ImplicitUsings ve Nullable açık bir .NET 10 konsol projesinde çalıştırabilirsin. Gerçek veritabanı bağlantısı gerekmiyor; önce üretim sözleşmesini küçük bir şema modeliyle sınamak daha kolay.

var columns = new[] { (Name:"Id", Type:"int"), (Name:"Title", Type:"string") };
static bool Identifier(string name) =>
    name.Length > 0 && (char.IsLetter(name[0]) || name[0] == '_') &&
    name.All(c => char.IsLetterOrDigit(c) || c == '_');
if (columns.Any(c => !Identifier(c.Name))) throw new ArgumentException("Invalid name");
var allowedTypes = new HashSet<string> { "int", "string", "decimal" };
if (columns.Any(c => !allowedTypes.Contains(c.Type))) throw new ArgumentException("Invalid type");
var fields = string.Join(", ", columns.Select(c => $"{c.Type} {c.Name}"));
Console.WriteLine($"public sealed record ItemDto({fields});");

İki kontrol farklı iş yapıyor. Identifier alan adının kaba biçimini denetler, allowedTypes üreticinin kabul ettiği tipleri sınırlar. Böylece Type alanına rastgele kod yazılması olağan girdi sayılmaz. Çıktıyı Console.WriteLine ile görmek faydalı, fakat başarı ölçütü derleyicinin bu dosyayı kabul etmesi olmalı.

Geçerli görünen ad neden derlenmeyebilir?

Bu Identifier yardımcısı tam C# sözdizimi kontrolü değildir. class harflerden oluşur ama anahtar sözcüktür. Id ve Id ayrı ayrı biçim kontrolünden geçer ama aynı record içinde iki parametre olamaz. Display Name ise boşluktan dolayı erken reddedilir. Üretim aracında anahtar sözcükleri kaçırma ya da reddetme, yinelenen adları bildirme ve normalize edilmiş adların çakışmasını bulma adımları eklerim.

Adı temizlerken sessiz dönüşümler de tehlikelidir. “Order Id” ile “Order-Id” değerlerini aynı OrderId adına dönüştürürsem hangi kolonu temsil ettiğim belirsizleşir. Kaynak ad, üretilen ad ve çakışma nedeni birlikte raporlanmalı. Roslyn'in dil servislerini kullanmak karakter kontrollerini büyüterek kendi küçük C# derleyicimi yazmaktan daha sağlam bir seçenek olur.

Tip eşleme yalnız int ve string seçmek değildir

Gerçek şemada null olabilirlik, decimal precision/scale, tarih türü ve uzunluk bilgisi vardır. NOT NULL bir text kolonu ile nullable text kolonu aynı DTO sözleşmesini üretmemeli. SQL Server uniqueidentifier ile PostgreSQL uuid benzer bir .NET tipe bağlanabilir, fakat sağlayıcı ayrıntılarını her şablona dağıtmak yerine ortak bir ara modelde toplarım.

Bu ara model veri toplama ile çıktı üretimini ayırır: önce şemadan ColumnDefinition benzeri kayıtlar çıkarılır, sonra aynı kayıtlarla DTO veya eşleme dosyası üretilir. Böylece bir sağlayıcı değişikliği tüm metin şablonlarını değiştirmez. Örnekte nullable analizi ve sağlayıcı dönüşümü yoktur; izin verilen üç tip yalnız küçük gösterimin kapsamıdır.

Üretilen dosyanın sahibi kim?

Tekrar üretimde geliştiricinin elle yazdığı iş kuralını silmek istemem. Üretilen dosyaları belirli bir dizinde tutar, özelleştirmeyi ayrı partial veya servis dosyasına bırakırım. Dosya adı ve çıktı yolu da sınırlanmalıdır; geçerli bir C# alan adı, güvenli bir dosya yolu garantisi değildir. Kullanıcı girdisinden doğrudan proje klasörü türetmem.

Belirleyici çıktı için kolon sırasını açıkça seçerim. Aynı şema iki çalıştırmada aynı dosyayı üretmeli; gereksiz tarih başlıkları ve makineye özgü yollar Git farkını gürültüye boğar. Dosyayı önce geçici konuma yazıp doğruladıktan sonra hedefe taşımak, yarım kalan üretimde çalışan kodun bozulma ihtimalini azaltır.

Üreticiyi çıktısıyla birlikte test etmek

Normal iki kolonun yanında boş ad, anahtar sözcük, mükerrer ad, desteklenmeyen tip ve nullable kolon senaryolarını denerim. Yalnız metnin beklenen biçimde olması yeterli değildir: örnek çıktıyı küçük bir projede derlemek dil hatasını, şemayla karşılaştırmak veri kaybını yakalar. Şablon büyüdükçe bu iki kontrolü ayırmak hata ayıklamayı da kolaylaştırır.

C# tanımlayıcı kuralları; Şemadan tersine model üretimi.

✳ Bu yörüngenin sonuna geldin.
Diğer yazıları keşfet →
turgay.Biraz kod, biraz piksel, bolca merak.© 2026 · Dünya’dan sevgilerle ✳