LINQ نوشتن کوئریها را خوانا و یکپارچه میکند، اما در پروژههای واقعی صرفاً استفاده از
Where
و
Select
کافی نیست. این مقاله با تمرکز بر کارایی و قابلیت نگهداری نشان میدهد چگونه فیلترهای داینامیک و Projectionهای دقیق بنویسیم تا هزینه پایگاهداده و حافظه کاهش یابد.
۱) فیلترهای پیشرفته و داینامیک
نمونه کد برای فیلترهای اختیاری:
var query = db.Users.AsQueryable();
if (!string.IsNullOrWhiteSpace(searchName))
query = query.Where(u => u.Name.Contains(searchName));
if (minAge.HasValue)
query = query.Where(u => u.Age >= minAge.Value);
if (maxAge.HasValue)
query = query.Where(u => u.Age <= maxAge.Value);
var users = await query
.OrderBy(u => u.Id)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.ToListAsync();
۲) Projectionهای کارا
فقط دادههای لازم را واکشی کنید:
var users = await db.Users
.Select(u => new { u.Id, u.Name })
.ToListAsync();
Projection به DTO:
public class UserDto
{
public string Name { get; set; }
public int OrderCount { get; set; }
}
var users = await db.Users
.Select(u => new UserDto
{
Name = u.Name,
OrderCount = u.Orders.Count()
})
.ToListAsync();
۳) Grouping و Aggregation
var report = await db.Orders
.GroupBy(o => o.CustomerId)
.Select(g => new
{
CustomerId = g.Key,
TotalOrders = g.Count(),
TotalAmount = g.Sum(o => o.Total)
})
.ToListAsync();
۴) نکات بهینهسازی EF Core
- استفاده از
AsNoTracking()
برای کوئریهای فقط-خواندنی. - انتخاب فقط ستونهای لازم با Projection.
- جلوگیری از N+1 Problem با Select شکلداده.
- استفاده از
AsSplitQuery()
در روابط چندگانه. - کامپایل کردن کوئریهای پرتکرار با
EF.CompileQuery
.
جمعبندی
با فیلترهای داینامیک، Projectionهای دقیق، Grouping و نکات EF Core میتوان کوئریهایی نوشت که هم سریع اجرا شوند و هم نگهداری سادهای داشته باشند. این مهارتها برای پروژههای واقعی ضروری هستند.