UZMAN
Keyless Entities — View & SP Mapping
Primary key'i olmayan sonuç setlerini (View'lar, Stored Procedure sonuçları, Raw SQL DTO'ları) EF Core modeline map eder. HasNoKey() ile tanımlanır, Change Tracking yapılmaz, salt okunurdur.
Veritabanı sağlayıcısı
Bu sayfadaki eşleşen örnekleri seçilen sağlayıcıya göre gösterir.
View Mapping
// DTO (keyless)
public class ProductSummary
{
public int CategoryId { get; set; }
public string CategoryName { get; set; } = null!;
public int ProductCount { get; set; }
public decimal AvgPrice { get; set; }
public decimal MaxPrice { get; set; }
}
// Configuration
public class ProductSummaryConfiguration : IEntityTypeConfiguration<ProductSummary>
{
public void Configure(EntityTypeBuilder<ProductSummary> builder)
{
builder.HasNoKey();
builder.ToView("vw_ProductSummary", "catalog");
}
}
// DbContext'e ekle
public DbSet<ProductSummary> ProductSummaries { get; set; }
SQL View
CREATE VIEW [catalog].[vw_ProductSummary] AS
SELECT
c.Id AS CategoryId,
c.Name AS CategoryName,
COUNT(p.Id) AS ProductCount,
AVG(p.Price) AS AvgPrice,
MAX(p.Price) AS MaxPrice
FROM catalog.Categories c
LEFT JOIN catalog.Products p ON p.CategoryId = c.Id
WHERE p.IsDeleted = 0
GROUP BY c.Id, c.Name;
CREATE VIEW catalog.vw_product_summary AS
SELECT
c.id AS category_id,
c.name AS category_name,
COUNT(p.id) AS product_count,
AVG(p.price) AS avg_price,
MAX(p.price) AS max_price
FROM catalog.categories c
LEFT JOIN catalog.products p ON p.category_id = c.id
WHERE p.is_deleted = FALSE
GROUP BY c.id, c.name;
Kullanım
// View üzerinden sorgulama (sadece okuma — insert/update/delete yapılamaz!)
var summaries = await context.ProductSummaries
.Where(s => s.ProductCount > 5)
.OrderByDescending(s => s.AvgPrice)
.ToListAsync();
Stored Procedure Sonucu
// SP sonucu için keyless entity
public class MonthlySalesReport
{
public int Year { get; set; }
public int Month { get; set; }
public decimal TotalRevenue { get; set; }
public int OrderCount { get; set; }
}
// Configuration
builder.HasNoKey();
builder.ToFunction("fn_MonthlySales"); // TVF için
// veya SP ile:
// Kullanım (SP)
var report = await context.Set<MonthlySalesReport>()
.FromSqlInterpolated($"EXEC sp_GetMonthlySales @Year={year}")
.ToListAsync();
Örnek View Çıktısı
| CategoryId | CategoryName | ProductCount | AvgPrice | MaxPrice |
|---|---|---|---|---|
| 1 | Elektronik | 45 | 12500.00 | 89999.99 |
| 2 | Giyim | 120 | 450.00 | 3500.00 |
| 3 | Kitap | 890 | 75.50 | 450.00 |
Kısıtlamalar: Keyless entity'ler track edilmez,
Add/Update/Removeçağrılamaz, navigation property'lere sahip olamaz (EF Core 8+: kısıtlı destek var).