TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #435 249
🆕 تازه‌های EF Core 10: عملگرهای LeftJoin و RightJoin در LINQ

اگر تا به حال با پایگاه‌های داده کار کرده باشی، حتماً با LEFT JOIN (و به‌صورت مشابه RIGHT JOIN) آشنا هستی. این یکی از اون چیزهایی‌ست که تقریباً همیشه ازش استفاده می‌کنیم.
اما در Entity Framework Core، انجام یک Left Join همیشه کمی دردسر داشت 😅

من از joinهایی خوشم میاد که دقیقاً مثل کاری که انجام میدن خونده بشن.
متأسفانه تا قبل از این، در LINQ راه مستقیمی برای بیان Left/Right Join وجود نداشت. باید از ترکیب GroupJoin و DefaultIfEmpty استفاده می‌کردی، که باعث می‌شد کدت پیچیده‌تر و سخت‌تر برای خواندن و نگهداری بشه.

اما خبر خوب اینه که 🎉 در 10 NET. این مشکل بالاخره برطرف شده، با معرفی متدهای جدید LeftJoin و RightJoin.

❓Left Join چیه؟ (به زبان ساده)

یک LEFT JOIN تمام ردیف‌ها از سمت چپ (Left side) و ردیف‌های منطبق از سمت راست رو برمی‌گردونه.
اگه تطابقی وجود نداشته باشه، سمت راست مقدار null می‌گیره.

🔹 دلیل استفاده: برای نگه داشتن داده‌های اصلی حتی زمانی که داده‌های مرتبط وجود ندارن.
مثلاً نمایش تمام محصولات، حتی اگر بعضی از اون‌ها هیچ Review‌ای نداشته باشن.

🕰 روش قدیمی (GroupJoin + DefaultIfEmpty)

قبل از 10 NET. ، برای انجام یک Left Join در LINQ باید از ترکیب GroupJoin و DefaultIfEmpty استفاده می‌کردی تا ردیف‌های سمت چپ بدون تطابق هم حفظ بشن.
این روش کار می‌کرد، اما مفهوم اصلی وسط کدهای اضافی گم می‌شد 😩

دو روش برای نوشتن این نوع query وجود داشت: Query Syntax و Method Syntax

🔹 Query Syntax
var query =
from product in dbContext.Products
join review in dbContext.Reviews on product.Id equals review.ProductId into reviewGroup
from subReview in reviewGroup.DefaultIfEmpty()
orderby product.Id, subReview.Id
select new
{
ProductId = product.Id,
product.Name,
product.Price,
ReviewId = (int?)subReview.Id ?? 0,
Rating = (int?)subReview.Rating ?? 0,
Comment = subReview.Comment ?? "N/A"
};



🧩 SQL
تولیدشده توسط EF Core برای query بالا:
SELECT
p."Id" AS "ProductId",
p."Name",
p."Price",
COALESCE(r."Id", 0) AS "ReviewId",
COALESCE(r."Rating", 0) AS "Rating",
COALESCE(r."Comment", 'N/A') AS "Comment"
FROM "Products" AS p
LEFT JOIN "Reviews" AS r ON p."Id" = r."ProductId"
ORDER BY p."Id", COALESCE(r."Id", 0)


⚙️ روش Method Syntax
var query = dbContext.Products
.GroupJoin(
dbContext.Reviews,
product => product.Id,
review => review.ProductId,
(product, reviewList) => new { product, subgroup = reviewList })
.SelectMany(
joinedSet => joinedSet.subgroup.DefaultIfEmpty(),
(joinedSet, review) => new
{
ProductId = joinedSet.product.Id,
joinedSet.product.Name,
joinedSet.product.Price,
ReviewId = (int?)review!.Id ?? 0,
Rating = (int?)review!.Rating ?? 0,
Comment = review!.Comment ?? "N/A"
})
.OrderBy(result => result.ProductId)
.ThenBy(result => result.ReviewId);

🧩 چرا این روش کار می‌کند:
• GroupJoin
ردیف‌های دو مجموعه را بر اساس شرط تطبیق می‌دهد،
• DefaultIfEmpty
زمانی که هیچ تطابقی وجود ندارد، یک مقدار پیش‌فرض (null) را درج می‌کند،
در نتیجه ردیف سمت چپ همچنان حفظ می‌شود.
سپس با SelectMany داده‌ها را تخت (flatten) می‌کنیم.

اما بیایید صادق باشیم 😅 —
برای چیزی به‌سادگی یک Left Join، این حجم از کد واقعاً زیادیه!

🚀 روش جدید در EF Core 10: استفاده از LeftJoin

الان می‌تونیم دقیقاً چیزی که مد نظر داریم رو بنویسیم.
LeftJoin
یک قابلیت رسمی در LINQ است و EF Core به طور خودکار آن را به LEFT JOIN در SQL ترجمه می‌کند.
var query = dbContext.Products
.LeftJoin(
dbContext.Reviews,
product => product.Id,
review => review.ProductId,
(product, review) => new
{
ProductId = product.Id,
product.Name,
product.Price,
ReviewId = (int?)review.Id ?? 0,
Rating = (int?)review.Rating ?? 0,
Comment = review.Comment ?? "N/A"
})
.OrderBy(x => x.ProductId)
.ThenBy(x => x.ReviewId);`

🧠 SQL تولیدشده توسط EF Core در این حالت دقیقاً مشابه مثال قبلی است.
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →