فصل 8 از 24 درس 1 از 1

LINQ و Query‌نویسی در EF Core

LINQ و Query‌نویسی در EF Core

بخشی از آموزش جامع ASP.NET Core Web API با .NET 10

محتوای درس 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، منطق برنامه و زیرساخت زمانی روشن می‌ماند که مسئولیت هر جزء به‌صورت صریح تعریف شود.

مفهومکارکرد
IQueryableQuery قابل ترجمه
Deferred Executionاجرای دیرهنگام
WhereFilter
SelectProjection
OrderBySort
Skip/TakePagination

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، امنیت و نیازهای نگهداری پروژه هماهنگ بماند.