LINQ و Queryنویسی در EF Core
LINQ و Queryنویسی در EF Core
محتوای درس LINQ و Queryنویسی در EF Core
.NET 10 | Filtering، Projection، Sorting و Pagination
LINQ زبان ساخت Query در .NET است و EF Core Expressionها را تا حد امکان به SQL ترجمه میکند. کیفیت Query به زمان Materialization، Projection، Tracking و ترتیب عملیات وابسته است.
این فصل با تمرکز بر قراردادهای قابل اتکا، مرزبندی مسئولیتها و رفتار قابل پیشبینی در محیط واقعی تنظیم شده است. مثالها بر پایه ASP.NET Core و .NET 10 نوشته شدهاند.
1. چارچوب موضوع و مفاهیم اصلی
LINQ زبان ساخت Query در .NET است و EF Core Expressionها را تا حد امکان به SQL ترجمه میکند. کیفیت Query به زمان Materialization، Projection، Tracking و ترتیب عملیات وابسته است.
واژگان و قراردادهای این بخش باید در سراسر پروژه یکدست بمانند؛ تفاوت میان لایه HTTP، منطق برنامه و زیرساخت زمانی روشن میماند که مسئولیت هر جزء بهصورت صریح تعریف شود.
| مفهوم | کارکرد |
|---|---|
| IQueryable | Query قابل ترجمه |
| Deferred Execution | اجرای دیرهنگام |
| Where | Filter |
| Select | Projection |
| OrderBy | Sort |
| Skip/Take | Pagination |
2. ساختار پیشنهادی در پروژه
Query ابتدا بهصورت IQueryable ساخته میشود، Filterها روی آن اعمال میشوند، سپس Sort و Pagination و در نهایت Projection یا Materialization انجام میشود. ToListAsync نباید زودتر از نیاز اجرا شود.
IQueryable<Product> query = db.Products.AsNoTracking();
if (!string.IsNullOrWhiteSpace(request.Search))
query = query.Where(p => p.Name.Contains(request.Search));
if (request.MinPrice.HasValue)
query = query.Where(p => p.Price >= request.MinPrice.Value);3. سناریوی اجرایی
برای List محصول، تنها Columnهای لازم Response انتخاب میشوند. TotalCount پیش از Skip/Take محاسبه و Sorting با Tie-breaker یکتا انجام میشود تا Pagination پایدار بماند.
در این سناریو، قرارداد ورودی و خروجی، مسیر شکست و رفتار قابل مشاهده سرویس باید پیش از جزئیات پیادهسازی مشخص شود. این رویکرد باعث میشود تغییرات بعدی بدون وابستگی پنهان و با امکان تست دقیق انجام شوند.
var totalCount = await query.CountAsync(cancellationToken);
var items = await query
.OrderBy(p => p.Name)
.ThenBy(p => p.Id)
.Skip((page - 1) * pageSize)
.Take(pageSize)
.Select(p => new ProductResponse(p.Id, p.Name, p.Price))
.ToListAsync(cancellationToken);4. اصول طراحی و نگهداری
پیادهسازی قابل نگهداری تنها به درست کار کردن در مسیر موفق محدود نیست. مرزهای مسئولیت، قابلیت مشاهده، امنیت، رفتار در خطا و امکان توسعه تدریجی باید همزمان بررسی شوند.
- Projection پیش از دریافت دادههای غیرضروری انجام شود.
- Sorting پویا از Allow-list فیلدهای مجاز استفاده کند.
- Collection بزرگ بدون Pagination بازگردانده نشود.
- SQL تولیدشده در Queryهای مهم بررسی شود.
5. خطاهای رایج و کنترل آنها
بخش مهمی از کیفیت یک API در نحوه جلوگیری از خطاهای تکرارشونده مشخص میشود. موارد زیر باید در بازبینی کد و تستهای قبل از انتشار کنترل شوند.
- ToList قبل از Filter و اجرای پردازش در حافظه.
- Includeهای متعدد و انفجار داده.
- Pagination بدون OrderBy یکتا.
- استفاده از Methodهای غیرقابل ترجمه در بخش SQL Query.
6. چکلیست نهایی فصل
- Query تا لحظه مناسب IQueryable باقی میماند.
- Read-only Query از AsNoTracking استفاده میکند.
- Projection دقیق تعریف شده است.
- Pagination و TotalCount رفتار مشخص دارند.
7. جمعبندی
مفاهیم این فصل زمانی کامل محسوب میشوند که هم مسیر موفق و هم مسیر خطا قابل پیشبینی، قابل تست و قابل مشاهده باشند. طراحی نهایی باید با Contract API، امنیت و نیازهای نگهداری پروژه هماهنگ بماند.