Giriş

Modern yazılım mimarisinde, veri akışını yönetmek için farklı nesne tipleri kullanırız: Entity, DTO ve ViewModel.
Peki, aralarındaki farklar neler?
Neden bu kadar ayrı nesneye ihtiyaç duyuyoruz?
Hangi katmanda hangisini kullanmalı, ne zaman hangisini tercih etmeli?

Bu yazıda:

  • Her bir nesne tipini kavramsal olarak,
  • C# kodları ile uygulamalı olarak,
  • Şemalar ve madde madde karşılaştırmalarla anlayacak ve büyük projelerde yapılan en yaygın hataları göreceksin.

viewmodel-dto-entity-giris

1. Entity Nedir?

Tanım

Entity, veritabanındaki gerçek tabloyu temsil eden nesnedir. Her Entity, genellikle ORM (Entity Framework, Dapper vs.) ile doğrudan eşleşir.

Temel Özellikler

  • DB tablosunun birebir modelidir.
  • Foreign Key, ilişkiler, navigation property’ler içerir.
  • Transaction ve persist işlemlerinde kullanılır.
  • Genellikle iş kuralları veya validasyon içermez.

C# Entity Örneği

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; } // Navigation property
}

2. DTO (Data Transfer Object) Nedir?

Tanım

DTO, iki katman arasında veri taşımak için kullanılan sade nesnedir. Sadece gerekli alanları içerir, genellikle iş kuralları veya ilişki içermez.

Temel Özellikler

  • Dış API, Service veya Controller ile veri alışverişinde kullanılır.
  • Sadece ihtiyaç duyulan alanlar bulunur.
  • DB bağımsızdır, annotation veya navigation property olmaz.
  • Güvenlik ve veri kısıtlama sağlar (fazla bilgiyi sızdırmaz).

C# DTO Örneği

public class ProductDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    // Kategori adı dışarı açılacaksa eklenebilir
    public string CategoryName { get; set; }
}

3. ViewModel Nedir?

Tanım

ViewModel, UI veya View katmanında, ekranın veya API çıktısının ihtiyacına göre düzenlenen veri modelidir. Ekstra görsel, validasyon, formatlama veya View’a özel property’ler içerebilir.

Temel Özellikler

  • UI veya API responsuna özeldir.
  • Birden fazla Entity/DTO’dan veri birleştirilebilir.
  • Formatlama, display özellikleri veya validation içerebilir.
  • Bazı durumlarda doğrudan UI ile binding yapılır (özellikle MVVM’de).

C# ViewModel Örneği

public class ProductViewModel
{
    public string Name { get; set; }
    public string CategoryName { get; set; }
    public string DisplayPrice { get; set; } // UI’da “₺50,00” gibi gösterim
    public bool IsDiscounted { get; set; }
}

4. Kavramsal Farklar Tablosu

Özellik Entity DTO ViewModel
Nerede Kullanılır DB/ORM, Repository Service, Controller, API UI, View, API Response
Ne İşe Yarar Tabloyu temsil eder Veri transferi Ekrana özel veri, format
İçerik Tüm tablo, ilişkiler Gerekli alanlar UI’ya özel alanlar, format
Annotation ORM (EF, Dapper, … ) Yok UI display, validation
Güvenlik Düşük (tüm veri) Orta (kısıtlı veri) Yüksek (UI’ya özel, filtre)
Navigation Prop Evet Hayır Gerekirse

5. Katmanlı Mimaride Kullanım Alanları

Akış Diyagramı

  • Entity: DB ve Repository’de kullanılır.
  • DTO: Servis, API, Controller arası iletişimde kullanılır.
  • ViewModel: UI, View, Frontend/Backend responsunda kullanılır.

Temel Akış

  1. Kullanıcı bir istek gönderir (ör: Ürün listele).
  2. Controller, Service katmanına isteği iletir.
  3. Service, Repository’den Entity nesnesi alır.
  4. Entity → DTO veya ViewModel’e dönüştürülür.
  5. Controller, DTO veya ViewModel’i kullanıcıya döner.

6. C# Kod Örnekleri ile Uygulama

Entity

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

DTO

public class ProductDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string CategoryName { get; set; }
}

ViewModel

public class ProductViewModel
{
    public string Name { get; set; }
    public string CategoryName { get; set; }
    public string DisplayPrice { get; set; }
    public bool IsDiscounted { get; set; }
}

Service ile Dönüşüm

public class ProductService
{
    private readonly IRepository<Product> _repo;
    public ProductService(IRepository<Product> repo) { _repo = repo; }

    public ProductDto GetProductDto(int id)
    {
        var entity = _repo.GetById(id);
        return new ProductDto
        {
            Id = entity.Id,
            Name = entity.Name,
            Price = entity.Price,
            CategoryName = entity.Category?.Name
        };
    }

    public ProductViewModel GetProductViewModel(int id)
    {
        var entity = _repo.GetById(id);
        return new ProductViewModel
        {
            Name = entity.Name,
            CategoryName = entity.Category?.Name,
            DisplayPrice = $"{entity.Price:C2}",
            IsDiscounted = entity.Price < 50
        };
    }
}

Otomatik Dönüşüm için Araçlar

C# projelerinde AutoMapper gibi araçlarla Entity-DTO-ViewModel dönüşümü kolayca yapılır.

// AutoMapper örnek kullanımı
var config = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Product, ProductDto>()
       .ForMember(dest => dest.CategoryName, opt => opt.MapFrom(src => src.Category.Name));
});
var mapper = config.CreateMapper();
ProductDto dto = mapper.Map<ProductDto>(productEntity);

7. Görseller & Diyagramlar

Katmanlı Mimari: Entity – DTO – ViewModel İlişkisi

viewmodel-dto-entity

8. Sıkça Sorulan Sorular

DTO ile ViewModel arasındaki temel fark nedir?
DTO daha çok servis ve veri transferinde, ViewModel ise UI ve ekrana özel datada kullanılır.
ViewModel’de ekstra validasyon, display formatı veya yalnızca UI’ya özgü alanlar olabilir.

Entity ile DTO arasındaki temel fark nedir?
Entity DB tablosunun aynısıdır, annotation ve navigation property içerir. DTO ise sadece dış dünyaya/servise açmak istediğin veriyi taşır.

Her projede üçü de şart mı?
Küçük projede çoğu zaman tek nesne yeterli olur. Büyük, ölçeklenebilir projede ayrım yapmak sürdürülebilirlik ve güvenlik sağlar.

9. Pratik İpuçları

  • Entity nesnesini asla doğrudan UI’a veya dış API’ya döndürme.
  • DTO, sadece gerçekten ihtiyaç duyulan alanları taşımalı.
  • ViewModel’de display/formatlama/validation eklemekten çekinme.
  • Dönüşümleri manuel yapmak yerine, AutoMapper gibi araçlar kullan (ama her zaman map’leri kontrol et).
  • Model değiştiğinde DTO/ViewModel’i güncellemeyi unutma.

10. En Sık Yapılan Hatalar

  • Entity’yi doğrudan API responsu veya UI’a döndürmek (tüm veritabanı alanları açığa çıkar).
  • DTO ve ViewModel’i birbirine karıştırmak.
  • Dönüşümleri tek yerde (service) değil, her yerde yapmak (dağınık kod).
  • Tüm alanları her nesneye koymak (ör: gereksiz navigation property’ler).
  • Güncel olmayan, senkronize olmayan modeller.

11. Sonuç

Büyük ve ölçeklenebilir projede, Entity, DTO ve ViewModel ayrımı sürdürülebilirlik, güvenlik, test edilebilirlik ve esneklik sağlar.
Her nesne yalnızca amacına uygun kullanılmalı;
Entity = DB/ORM,
DTO = veri transferi,
ViewModel = UI/ekran özel ihtiyaçları.

12. Kaynaklar

By tanju.bozok

Software Architect, Developer, and Entrepreneur

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir