ูุจู ู
ุง ูุจุฏุฃ ูุชููู
ุนู ุงูู LINQ ููู ุฅูู ุฃุตููุงุ ููุงุฎุฏ ู
ูุฏู
ุฉ ุจุณูุทุฉ ุนู ู
ุดููุฉ ูุงุจูุชูุง ูููู
ุดู ุฎุทูุฉ ุจุฎุทูุฉ ูุญุฏ ู
ุง ูุญููุง ุจุฃุญุณู ุทุฑููุฉ.
ูุฏู ูููุถุญ ููุง ุฅูู ูุงูุฏุฉ ุงูู LINQ ูุงููุงุณ ุงููู ุนู
ูููุง ูุงููุง ุจูููุฑูุง ุฅุฒุงู.
ูุจู ู ุง ูุจุฏุฃ
ูุจุฏุฃ ุจู ุซุงู ุจุณูุท ูููู ู ูู ูุงูุฏุชูุง ูุฅุฒุงู ุนู ููุงูุง ููููุ
ููุนู
ู Class ุงุณู
ู Employee ููุนู
ู ู
ูู List.
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public string Address { get; set; }
}
// In Main method or wherever you initialize
List<Employee> employees = new List<Employee>
{
new Employee { Id = 1, Name = "Ahmed", Gender = "Male", Salary = 6000, Address = "Cairo" },
new Employee { Id = 2, Name = "Salma", Gender = "Female", Salary = 4500, Address = "Alex" },
new Employee { Id = 3, Name = "Ali", Gender = "Male", Salary = 8000, Address = "Cairo" },
new Employee { Id = 4, Name = "Sara", Gender = "Female", Salary = 4800, Address = "Tanta" },
// Add more employees as needed
};Printing List of object
ู ู ูู ูุณุชุฎุฏู ุงูู Foreach ุนุดุงู ูุทุจุน ุงูููุณุชุฉ ุฏู.
foreach (var employee in employees)
{
Console.WriteLine(employee);
}
// Output will likely be something like:
// YourNameSpace.Employee
// YourNameSpace.Employee
// ...ูููุงูู ุฅูู ุจูุทุจุน ุงุณู
ุงูู namespace ูุงุณู
ุงูู class ุจุงูุดูู ุฏู. ุฏู ุจุณุจุจ ุงูู ToString() method ุงููู ู
ูุฌูุฏุฉ ุชููุงุฆู ูู ุงูู System.Objectุ ุงููู ุฃู class ูู C# ุจููุฑุซ ู
ูู ุจุดูู ุชููุงุฆู.
ุนุดุงู ูุฎูู ุงูุทุจุงุนุฉ ุดูููุง ุฃุญุณูุ ู
ู
ูู ูุนู
ู override ููู ToString() method ุฏู ุฌูู ุงูู Employee class.
// Inside Employee Class
public override string ToString()
{
// Customize the string representation
return $"Id: {Id} - Name: {Name} - Gender: {Gender} - Salary: {Salary} - Address: {Address}";
}ุฏูููุชู ูู ุทุจุนูุง ุชุงููุ ููุธูุฑ ุจูุงูุงุช ูู ู ูุธู ุจุดูู ุฃูุถุญ.
ู ูุฏู ุฉ: ูุนู ู Query ููุฏุงุชุง
ููุชุฑุถ ุฅููุง ุนุงูุฒูู ูุฌูุจ ูู ุงูู ูุธููู ุงููู ุงูู ุฑุชุจ ุจุชุงุนูู ุฃูู ู ู 5000 ุฌููู.
ุงูู ูุธููู ุงููู ู ุฑุชุจูู ุฃูู ู ู 5000
ุงูุทุฑููุฉ ุงููุฏูู ุฉ (Old way)
ููุง ุจูุนู
ู loop ููุญุท if condition ููุถูู ุงูู
ูุธููู ุงููู ุจูุญูููุง ุงูุดุฑุท ูู list ุฌุฏูุฏุฉ.
List<Employee> filteredList = new List<Employee>();
foreach (var employee in employees)
{
if (employee.Salary < 5000)
{
filteredList.Add(employee);
}
}
// Print the filtered list
Console.WriteLine("Employees with Salary < 5000:");
foreach (var employee in filteredList)
{
Console.WriteLine(employee); // Uses the overridden ToString()
}ู ุดููุฉ ุงูุทุฑููุฉ ุฏู:
- ูู ุงุณุชุฎุฏู
ูุง ููุณ ุงูู
logicุฏู (ุงูู ุฑุชุจ ุฃูู ู ู 5000) ูู ุฃูุชุฑ ู ู ู ูุงู ูู ุงูููุฏุ ูุฌููุง ุจุนุฏ ูุฏู ุญุจููุง ูุบูุฑ ุงูุดุฑุท (ู ุซููุง ูุฎููู ุฃูู ู ู 6000)ุ ููุถุทุฑ ูุนุฏูู ูู ูู ุงูุฃู ุงูู ุฏู. ุฏู ุจูุฒูุฏ ุงุญุชู ุงููุฉ ุงูุฎุทุฃ ูุจูุตุนุจ ุงูุตูุงูุฉ.
ูุงูุญู ุฅููุง ูุนู
ู Method ุจุชุนู
ู ุงูููุชุฑุฉ ุฏูุ ุนุดุงู ูู ุญุจููุง ูุบูุฑ ุงูู logicุ ูุบูุฑู ูู ู
ูุงู ูุงุญุฏ ุจุณ. ูุงูุฃุญุณู ูู
ุงู ุฅููุง ูุนู
ููุง ูู Extension Method ุนุดุงู ุชุจูู ุณููุฉ ุงูุงุณุชุฎุฏุงู
ู
ุน ุฃู List<Employee>.
ูุนู ู ู ูุซูุฏ (Make Method)
ููุนู
ู static class ููุถูู ููู extension method ููู List<Employee>.
public static class ListExtensions
{
// Specific filter method (not ideal)
public static List<Employee> FilterEmployeesWithSalaryLessThan5000(this List<Employee> employees)
{
List<Employee> filteredEmployees = new List<Employee>();
foreach (var employee in employees)
{
if (employee.Salary < 5000)
{
filteredEmployees.Add(employee);
}
}
return filteredEmployees;
}
}
// How to use it:
// var filteredByMethod = employees.FilterEmployeesWithSalaryLessThan5000();ูุฏู ุญูููุง ู ุดููุฉ ุชูุฑุงุฑ ุงูููุฏ ูุชุนุฏููู ูู ูุฐุง ู ูุงู.
ุทูุจุ ูู ุนุงูุฒ ุฃุนู
ู ููุชุฑุฉ ุชุงููุฉุ ู
ุซููุงุ ุฃุฌูุจ ุงูู
ูุธููู ุงูุฐููุฑ ุจุณ (Gender == "Male") ุฃู ุงููู ุณุงูููู ูู ุทูุทุง (Address == "Tanta")ุ ูู ูุนู
ู method ุฌุฏูุฏุฉ ููู ุดุฑุทุ ุฃููุฏ ูุฃ.
ุงุณุชุฎุฏุงู ุงูู Delegate
ูู ุจุตููุง ุนูู ุงูู methods ุงููู ู
ู
ูู ูุนู
ููุง ููููุชุฑุฉ ุงูู
ุฎุชููุฉ:
// Filter by Tanta Address (Old way - specific method)
public static List<Employee> FilterEmployeesFromTanta(this List<Employee> employees)
{
List<Employee> filteredEmployees = new List<Employee>();
foreach (var employee in employees)
{
if (employee.Address == "Tanta") // The only difference is this condition
{
filteredEmployees.Add(employee);
}
}
return filteredEmployees;
}
// Filter Male Employees (Old way - specific method)
public static List<Employee> FilterMaleEmployees(this List<Employee> employees)
{
List<Employee> filteredEmployees = new List<Employee>();
foreach (var employee in employees)
{
if (employee.Gender == "Male") // The only difference is this condition
{
filteredEmployees.Add(employee);
}
}
return filteredEmployees;
}ูููุงุญุธ ุฅู ุงููุฑู ุงููุญูุฏ ุจูู ุงูู methods ุฏู ูู ุงูุดุฑุท (if condition).
ุงูุญู ููุง ุฅููุง ูุฎูู ุงูู method ุจุชุงุนุฉ ุงูููุชุฑุฉ ุชุงุฎุฏ ุงูุดุฑุท ุฏู ูู parameter. ูุนุดุงู ุงูุดุฑุท ุฏู ุนุจุงุฑุฉ ุนู function ุตุบูุฑุฉ ุจุชุฑุฌุน true ุฃู falseุ ููุณุชุฎุฏู
delegate ู
ูุงุณุจ. ุงูู delegate ุงูุฃูุณุจ ููุง ูู Predicate ูุฅููุง ุจุชุงุฎุฏ parameter ู
ู ููุน T (ุงููู ูู Employee ูู ุญุงูุชูุง) ูุจุชุฑุฌุน bool.
// In the ListExtensions class
public static class ListExtensions
{
// Generic filter method using Predicate delegate
public static List<Employee> FilterEmployees(this List<Employee> employees, Predicate<Employee> predicate)
{
List<Employee> filteredEmployees = new List<Employee>();
foreach (var employee in employees)
{
// Call the predicate to check the condition
if (predicate(employee))
{
filteredEmployees.Add(employee);
}
}
return filteredEmployees;
}
}
// In the Main method or wherever you call it:
// Define boolean methods matching the Predicate signature
public static bool IsMaleEmployee(Employee employee)
{
return employee.Gender == "Male";
}
public static bool IsSalaryLessThan5000(Employee employee) // Changed from 8000 in original text
{
return employee.Salary < 5000;
}
public static bool IsFromTanta(Employee employee)
{
return employee.Address == "Tanta";
}
// Call the generic filter method, passing the condition method as a parameter
var maleEmployees = employees.FilterEmployees(IsMaleEmployee);
var lowSalaryEmployees = employees.FilterEmployees(IsSalaryLessThan5000);
var tantaEmployees = employees.FilterEmployees(IsFromTanta);
// Print results (example for males)
Console.WriteLine("\nMale Employees:");
foreach (var employee in maleEmployees)
{
Console.WriteLine(employee);
}ูุจูุฏู ุงูู
ุดููุฉ ุจูุช ู
ุญูููุฉ ุจุดูู ูููุณ ุฌุฏูุง. ุนูุฏูุง method ูุงุญุฏุฉ ููููุชุฑุฉุ ูุจูู
ุฑุฑ ููุง ุงูุดุฑุท ุงููู ุนุงูุฒููู.
ุทูุจุ ูู ุงุญุชุฌูุง ูุนู
ู class ุฌุฏูุฏุ ู
ุซููุง Productุ ููุนู
ู ูู ููุชุฑุฉ ุจููุณ ุงูุทุฑููุฉุ ูู ูููุฑุฑ ููุณ ุงูู FilterEmployees method ููุนู
ู FilterProductsุ ุฃููุฏ ูุฃ.
ููุง ููุฌู ุฏูุฑ ุงูู Generics.
ุงุณุชุฎุฏุงู ุงูู Cs Generics
ุนุดุงู ูุฎูู ุงูู Filter method ุจุชุงุนุชูุง ุชุดุชุบู ู
ุน ุฃู type (ุณูุงุก Employee ุฃู Product ุฃู ุบูุฑู)ุ ููุณุชุฎุฏู
ุงูู Generics. ููุฎูู ุงูู method ุชุงุฎุฏ type parameter (T) ูุชุดุชุบู ุนููู.
// Updated ListExtensions class with Generics
public static class GenericListExtensions // Renamed for clarity
{
// Generic Filter method using Generics and Predicate
public static List<T> Filter<T>(this List<T> items, Predicate<T> predicate)
{
List<T> filteredItems = new List<T>();
foreach (var item in items)
{
if (predicate(item))
{
filteredItems.Add(item);
}
}
return filteredItems;
}
}
// Example Product class
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public double Price { get; set; }
public override string ToString() => $"Id: {Id}, Name: {Name}, Category: {Category}, Price: {Price}";
}
// In Main method:
List<Product> products = new List<Product>
{
new Product { Id = 101, Name = "Laptop", Category = "Devices", Price = 25000 },
new Product { Id = 102, Name = "Keyboard", Category = "Devices", Price = 1500 },
new Product { Id = 103, Name = "T-Shirt", Category = "Clothing", Price = 500 },
new Product { Id = 104, Name = "Mouse", Category = "Devices", Price = 800 },
};
// Define predicate methods for Product
public static bool IsDeviceAndLessThan20000(Product product)
{
return product.Category == "Devices" && product.Price < 20000;
}
// Call the generic Filter method
var filteredEmployeesGeneric = employees.Filter<Employee>(IsMaleEmployee); // Specify Employee type
var filteredProductsGeneric = products.Filter<Product>(IsDeviceAndLessThan20000); // Specify Product type
// Print results (example for products)
Console.WriteLine("\nFiltered Products (Devices < 20000):");
foreach (var product in filteredProductsGeneric)
{
Console.WriteLine(product);
}ุฏูููุชู ุงูู Filter<T> method ุจูุช ุดุบุงูุฉ ู
ุน ุฃู List ูุฃู ุดุฑุท.
ุนุดุงู ูุฎูู ุงูู Syntax ุฃุณูู ูุฃูุชุฑ ุงุฎุชุตุงุฑูุงุ ุจุฏู ู
ุง ูุนู
ู method ู
ููุตูุฉ ููู ุดุฑุท (ุฒู IsMaleEmployee ู IsDeviceAndLessThan20000)ุ ู
ู
ูู ูุณุชุฎุฏู
Lambda Expressions in Csharp. ุบุงูุจูุง ู
ุด ููุญุชุงุฌ ูุณุชุฎุฏู
ุงูู methods ุฏู ุชุงููุ ูุงูู Lambda ุจุชููู ุฃูุณุจ.
// Using Lambda Expressions directly with the Filter method
var filteredEmployeesLambda = employees.Filter(employee => employee.Gender == "Male");
var filteredProductsLambda = products.Filter(product => product.Category == "Devices" && product.Price < 20000);
// Note: We don't need to specify <Employee> or <Product> because the compiler infers it.
// Print results (example for products lambda)
Console.WriteLine("\nFiltered Products (Lambda):");
foreach (var product in filteredProductsLambda)
{
Console.WriteLine(product);
}Where (LINQ)
ูู ุงููู ุนู
ููุงู ููู ุฏู ุนุดุงู ููุตู ูู method ููุชุฑุฉ ุนุงู
ุฉ ูู
ุฑูุฉุ ูู ุจุงูุธุจุท ุงููู LINQ ุจููุฏู
ููููุง ุฌุงูุฒ ูู operator ุงุณู
ู Where.
ุงูู Where ูู Filtration Operator ูู LINQ.
// The Filter<T> method we created:
// var filteredProductsManual = products.Filter(product => product.Category == "Devices" && product.Price < 20000);
// Using LINQ's built-in Where (Fluent Syntax):
var filteredProductsLinqFluent = products.Where(product => product.Category == "Devices" && product.Price < 20000);
// Using LINQ's built-in Where (Query Syntax):
var filteredProductsLinqQuery = from p in products // p is a range variable representing each product
where p.Category == "Devices" && p.Price < 20000
select p; // Select the product itself
// Print results (example for LINQ Fluent)
Console.WriteLine("\nFiltered Products (LINQ Fluent Where):");
foreach (var product in filteredProductsLinqFluent)
{
Console.WriteLine(product);
}ุฒู ู
ุง ุฅูุช ุดุงููุ LINQ ุจูููุฑ ููุง Where ุงููู ุจุชุนู
ู ููุณ ูุธููุฉ ุงูู Filter<T> ุจุชุงุนุชูุงุ ุจุณ ุจุดูู ู
ุฏู
ุฌ ูู ุงููุบุฉ.
Indexed Where
ุงูู Where method ูููุง overload.
- ุงูุฃูู (ุงููู ุงุณุชุฎุฏู
ูุงู): ุจูุงุฎุฏ
parameterูุงุญุฏ ุจุณ (ุงููู ูู ุงููpredicateุงููู ุจูุดุชุบู ุนูู ุงูุนูุตุฑ ููุณูุ ุฒูproduct => ...). - ุงูุชุงูู (Indexed Where): ุจูุงุฎุฏ ุงุชููู
parameters:- ุงูุนูุตุฑ ููุณู (
product). - ุงูู
indexุจุชุงุน ุงูุนูุตุฑ ุฏู ูู ุงููsequence(ุจูุจุฏุฃ ู ู 0).
- ุงูุนูุตุฑ ููุณู (
ูู
ุซููุงุ ูู ุนุงูุฒ ุฃุฌูุจ ุฃูู 10 ู
ูุชุฌุงุช ุจุดุฑุท ูููููุง ู
ู ููุน Devices:
// Using Indexed Where (Fluent Syntax only)
var first10Devices = products.Where((p, index) => index < 10 && p.Category == "Devices");
Console.WriteLine("\nFirst 10 Devices (Indexed Where):");
foreach (var product in first10Devices)
{
Console.WriteLine(product);
}ู
ูุญูุธุฉ ู
ูู
ุฉ: ุงูู Indexed Where ุฏู ู
ุชุงุญ ุจุณ ูู ุงูู Fluent Syntax (ุทุฑููุฉ ุงูู methods)ุ ูู
ุด ู
ุชุงุญ ูู ุงูู Query Syntax (ุทุฑููุฉ from...where...select). ูููุถุญ ุงููุฑู ุจูููู
ุชุญุช.
LINQ
ู ูุฏู ุฉ
- LINQ stands for Language Integrated Query. (ุงุณุชุนูุงู ู ุฏู ุฌ ูู ุงููุบุฉ).
- ุจููุฏุฑ ูุนู
ู ุจููุง
Queries(ุงุณุชุนูุงู ุงุช) ุนูู ุงูุฏุงุชุง ุจุชุงุนุชูุง ุจุณูููุฉ ุฌูู ุงูููุฏ ุจุชุงุน C#. - ูู ุนุจุงุฑุฉ ุนู ู
ุฌู
ูุนุฉ ูุจูุฑุฉ ู
ู ุงูู
functions(ุฃูุชุฑ ู ู 40ุ ููู ูุงุญุฏุฉ ูููุง ุฃูุชุฑ ู ูoverload). - ุงูู
functionsุฏู ูู ุงูุญูููุฉ ุนุจุงุฑุฉ ุนู Extension Methods ู ุนู ููุฉ ูููinterfaceุงููู ุงุณู ู IEnumerable ูุฃูclassุจูุนู ู ููimplementุฃู ุจููุฑุซ ู ูู (ุฒูList,Array, IReadOnlyList ูุบูุฑูู ูุชูุฑ). - ุงูู
functionsุฏู ุจูุณู ููุง ุจุฑุถู LINQ Operators ููููู ู ูุฌูุฏูู ุฌููstatic classุงุณู ู Enumerable. - ุงูู
Operatorsุฏู ู ุชูุณู ุฉ ูู 13 Category (ู ุฌู ูุนุฉ) ุญุณุจ ูุธููุชูุง (ุฒู Filtration, Projection, Ordering, Grouping, etc.). - ุทุจุนูุงุ ุงูู
Return typeุจุชุงุน ู ุนุธู ุงููLINQ operatorsุจููููIEnumerable(ุฃูIQueryableุฒู ู ุง ููุดูู)ุ ูู ู ูู ูุญูู ุงููุชูุฌุฉ ุฏู ููListุฃูArrayุจุณูููุฉ ูู ู ุญุชุงุฌูู (ุจุงุณุชุฎุฏุงูToList()ุฃูToArray()).
ุทุจ ุฅูู ุนูุงูุชูุง ุจุงูู Databases ููุงูุฏุชูุงุ
- ุงูู
LINQ functionsุฃูOperatorsุฏู ุชุนุชุจุฑ ุชุทุจูู ูููconceptsุจุชุงุนุฉ ูุบุฉ ุงุณุชุนูุงู ุงูุจูุงูุงุช ุงูููุงุณูุฉSQLุ ูุจุงูุชุญุฏูุฏ ุงูุฌุฒุก ุงูุฎุงุต ุจุงูู Data Query Language (DQL) ุงููู ูู ุฃู ุฑSELECTุจูู ุงูุฅู ูุงููุงุช ุงููู ู ุนุงู (ุฒูWHERE,ORDER BY,GROUP BY,JOIN). ูุนูู ูุฃููุง ุฎุฏูุง ุงููSELECTstatement ูุญุทููุงูุง ุฌูู C#. - ุงููุงุฆุฏุฉ ุงููุจูุฑุฉ: ุจุฏู ู
ุง ููุชุจ
SQL queryุตุฑูุญ ูู ุงูููุฏ ุจุชุงุนูุง (ูุฏู ููุฎูููุง ู ุฑุชุจุทูู ุจูdatabase serverู ุนูู ุฒู SQL Server ุฃู MySQL)ุ ุจููุชุจLINQ query. - ุงูู
LINQ queryุฏู ุจูููู ู ุณุชูู ุนู ููุน ุงููdatabase. - ูู
ุง ุจูุณุชุฎุฏู
LINQู ุนframeworkุฒู Entity Framework Core (Route Course MOC)ุ ุงููEF Coreูู ุงููู ุจูุชููู ู ูู ุฉ ุชุฑุฌู ุฉ ุงููLINQ queryุจุชุงุนูุง ููSQL queryู ูุงุณุจ ูููDatabase Management System (DBMS)ุงููู ุฅุญูุง ุดุบุงููู ุนููู (ุณูุงุก ูุงู SQL Server, PostgreSQL, SQLite, etc.). - ุฏู ุจูุฎูู ุงูููุฏ ุจุชุงุนูุง
portableุฃูุชุฑุ ูู ุญุจููุง ูุบูุฑ ููุน ุงููdatabaseูู ุงูู ุณุชูุจูุ ู ุด ููุญุชุงุฌ ูุบูุฑ ุงููLINQ queriesุจุชุงุนุชูุง.
Sequence (ุงูู ุชุณูุณูุฉ)
ุฅุญูุง ุจูุณุชุฎุฏู
ุงูู LINQ Operators ู
ุน ุงูุฏุงุชุง ุงููู ุจุชููู ู
ุชุฎุฒูุฉ ูู ุดูู Sequence (ู
ุชุณูุณูุฉ)ุ ุจุบุถ ุงููุธุฑ ูู ู
ุชุฎุฒูุฉ ููู.
ูู
ุง ูููู โSequenceโุ ุจููุตุฏ ุฃู Object ุจูุทุจู ุงูู interface ุงููู ุงุณู
ู Cs IEnumerable (ูุฏู ู
ุนูุงู ุฅููุง ููุฏุฑ ูุนู
ู ุนููู loop ุจุงุณุชุฎุฏุงู
foreach). ุฃู
ุซูุฉ ุฒู: List<T>, T[] (Array), Dictionary<TKey, TValue>, string, ูุบูุฑูุง ู
ู ุงูู Collections.
ุงูุชูุณูู ูู โLocalโ ู โRemoteโ ุจูุนุชู ุฏ ุนูู ู ุตุฏุฑ ุงูุฏุงุชุง:
-
Local Sequence:
- ูู ุฃู
Sequenceู ูุฌูุฏุฉ ูู ุงูุฐุงูุฑุฉ (in-memory) ุจุชุงุนุฉ ุงูุฃุจูููุดู ุจุชุงุนูุ ุฒูListุฃูArrayุนู ูุชูู ุจููุณู. - ูู
ุง ุจุชุณุชุฎุฏู
LINQู ุนุงูุงุ ุงูุนู ููุฉ ุฏู ุจูุณู ููุง LINQ to Objects (L2O). - ููู ูู
ุงู LINQ to XML (L2XML) ูู ุจุชุนู
ู
queryุนูู ูุงูู XML files ู ูุฌูุฏ ุนูุฏู. - ูู ุงูุนู
ููุงุช (ุงูููุชุฑุฉุ ุงูุชุฑุชูุจุ ุฅูุฎ) ุจุชุญุตู ุฌูู ุงูู
RAMุจุชุงุนุฉ ุงูุฌูุงุฒ ุงููู ุดุบุงู ุนููู ุงูุฃุจูููุดู. ู ููุด ุงุชุตุงู ุจู ุตุฏุฑ ุฎุงุฑุฌู. - ุญุชู ูุงููุงุช ุงูู
XMLุจูุนุชุจุฑูุงLocalูู ุงูุณูุงู ุฏู.
- ูู ุฃู
-
Remote Sequence:
- ูู
Sequenceุงูุฏุงุชุง ุจุชุงุนุชูุง ู ุด ู ูุฌูุฏุฉ ู ุจุงุดุฑุฉ ูู ุงูุฐุงูุฑุฉุ ููููุง ุฌุงูุฉ ู ู ู ุตุฏุฑ ุจูุงูุงุช ุฎุงุฑุฌู (external data source). - ุฃุดูุฑ ู
ุซุงู ูู ูุงุนุฏุฉ ุงูุจูุงูุงุช (Database). ุฃู
ุซูุฉ ุชุงููุฉ ู
ู
ูู ุชููู
Web APIุฃู ุฃู ุฎุฏู ุฉ ุจุชููุฑ ุฏุงุชุง. - ูู
ุง ุจูุดุชุบู ู
ุน
remote sequences(ุฎุตูุตูุง ู ุนdatabasesุจุงุณุชุฎุฏุงูEF Core)ุ ุบุงูุจูุง ุจูุชุนุงู ู ู ุนinterfaceุชุงูู ุงุณู ู Cs IQueryable ุจุฏูIEnumerable<T>. - ุงูู
IQueryable<T>ุจูุณู ุญ ุจุชุฑุฌู ุฉ ุงููLINQ queryููquery languageูููู ูุง ุงูู ุตุฏุฑ ุงูุฎุงุฑุฌู (ุฒูSQLูู ุญุงูุฉ ุงููdatabase). - ุงูุนู
ููุงุช ุฏู ุจูุณู
ููุง LINQ to SQL (ููู
SQL Serverุจุดูู ู ุจุงุดุฑ ุฒู ุงู)ุ LINQ to Entities (ู ุนEntity FrameworkูEF Core)ุ ุฃู LINQ to OData (ูู ุจุชูููOData API). - ุงูู
Queryููุณู ุจูุชููุฐ ุนูู ุงููserverุฃู ุงูู ุตุฏุฑ ุงูุฎุงุฑุฌูุ ูุจุนุฏูู ุงููุชูุฌุฉ ุจุณ ูู ุงููู ุจุชุฑุฌุน ููุฃุจูููุดู ุจุชุงุนู.
- ูู
ุจุงุฎุชุตุงุฑ:
- ุงูู Local Sequence: ู
ูุฌูุฏุฉ ุฌูู ุงูุฃุจูููุดู ูุชูุฏุฑ ุชูู ุนูููุง ุจู
foreachูู ุงููmemoryุนูุทูู. - ุงูู Remote Sequence: ุจุชู
ุซู ุฏุงุชุง ู
ูุฌูุฏุฉ ุจุฑู ุงูุฃุจูููุดู (ุฒู
database table)ุ ุงููqueryุจูุชููุฐ ููุงู ูุงููุชูุฌุฉ ุจุชุฑุฌุนูู.
Query Syntax vs Fluent Syntax
ููู ุทุฑููุชูู ุฃุณุงุณูุชูู ููุชุงุจุฉ LINQ queries ูู C#:
ุงูููุน ุงููู ูู ุงูู Method ุฏุง ุงุณู
ู Fluent ุจุฑุถู.
1. Fluent Syntax (Method Syntax)
ุฏู ุงูุทุฑููุฉ ุงููู ุจูุณุชุฎุฏู
ูููุง ุงูู LINQ operators ูุฃููุง methods ุจููุงุฏููุง ุนูู ุงูู sequence ุจุชุงุนุชูุง. ูููุง ุดูููู:
- ุงูู Extension Method (ุงูุทุฑููุฉ ุงูุดุงุฆุนุฉ ูุงูู
ูุถูุฉ): ุจููุงุฏู ุงูู
operatorููextension methodู ุจุงุดุฑุฉ ุนูู ุงููListุฃู ุงููIEnumerableุจุชุงุนูุง. - ุงูู Static Method: ุจููุงุฏู ุงูู
operatorููstatic methodู ู ุงููEnumerableclass ูุจูู ุฑุฑ ูู ุงููsequenceูุฃููparameter.
List<int> Numbers = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
IEnumerable<int> OddNumbers; // Result will be IEnumerable
// ุงูุทุฑููุฉ ุงูุฃููู (Static Method - ู
ุด ุจูุณุชุฎุฏู
ูุง ูุชูุฑ ุฃูู)
// Enumerable.Where(Source_Sequence, Predicate_Lambda)
OddNumbers = Enumerable.Where(Numbers, N => N % 2 == 1);
Console.WriteLine("Odd Numbers (Static Method): " + string.Join(", ", OddNumbers));
// ุงูุทุฑููุฉ ุงูุชุงููุฉ (Extension Method - ุฏู ุงููู ุจูุณุชุฎุฏู
ูุง ุฏุงูู
ูุง)
OddNumbers = Numbers.Where(N => N % 2 == 1);
Console.WriteLine("Odd Numbers (Extension Method): " + string.Join(", ", OddNumbers));ุงูู Fluent Syntax (ุฎุตูุตูุง ุทุฑููุฉ ุงูู Extension Method) ูู ุงูุฃูุซุฑ ุงุณุชุฎุฏุงู
ูุง ูู
ุฑููุฉุ ุฎุตูุตูุง ู
ุน ุงูุนู
ููุงุช ุงูู
ุนูุฏุฉ ุฃู ุงูู
ุชุณูุณูุฉ (chaining).
2. Query Syntax (Query Expression Syntax)
- ุฏู ุทุฑููุฉ ูุชุงุจุฉ
LINQุจุดูู ุดุจู ูุบุฉSQL. - ุจุชุจุฏุฃ ุฏุงูู
ูุง ุจููู
ุฉ
fromุงููู ุจุชุนุฑูrange variableุจูู ุซู ูู ุนูุตุฑ ูู ุงููsequence(ุฒูNูู ุงูู ุซุงู ุชุญุช). - ุจุนุฏูุง ุจุชูุฌู ุฌู
ู ุฒู
where,orderby,select,group,join. - ูุงุฒู
ุชูุชูู ุจู
selectุฃูgroup by. - ุงูุชุฑุชูุจ ุจุชุงุน ุงูุฌู
ู ูู ุงูู
Query Syntaxุจูููู ู ุฎุชูู ุดููุฉ ุนูSQL(ู ุซููุงselectุจุชูุฌู ูู ุงูุขุฎุฑ).
// Query Syntax example for odd numbers
OddNumbers = from N in Numbers // Define range variable N for each item in Numbers
where N % 2 == 1 // Filter condition
select N; // Select the item itself
Console.WriteLine("Odd Numbers (Query Syntax): " + string.Join(", ", OddNumbers));ุงูู Query Syntax ู
ู
ูู ุชููู ุฃุณูู ูู ุงููุฑุงุกุฉ ูุจุนุถ ุงููุงุณ ุงููู ู
ุชุนูุฏูู ุนูู SQLุ ุฎุตูุตูุง ู
ุน ุนู
ููุงุช ุงูู Join ูุงูู Grouping.
3. Hybrid Syntax (ุงูุฎููุท)
- ุฃุญูุงููุง ุจูุญุชุงุฌ ูุณุชุฎุฏู
operatorู ุด ู ูุฌูุฏ ุฃู ุตุนุจ ุงุณุชุฎุฏุงู ู ูู ุงููQuery Syntax(ุฒูCount(),FirstOrDefault(),Take(),Skip(), ูุบูุฑูุง ูุชูุฑ). - ูู ุงูุญุงูุฉ ุฏูุ ู
ู
ูู ููุชุจ ุฌุฒุก ู
ู ุงูู
queryุจุงููQuery Syntaxุ ููุญุท ุงููุชูุฌุฉ ุจูู ููุณูู()ุ ูุจุนุฏูู ููู ู ุนููู ุจุงููFluent Syntax.
// Example: Get the first product that is out of stock using Hybrid Syntax
// Assuming ProductList is a List<Product>
// var Result = (from P in ProductList // Query Syntax part
// where P.UnitsInStock == 0
// select P)
// .FirstOrDefault(); // Fluent Syntax part added after the query
// Example with the sample data (find first product with price < 1000)
var firstCheapProduct = (from p in products
where p.Price < 1000
select p)
.FirstOrDefault(); // Returns the Mouse product or null if none found
if (firstCheapProduct != null)
{
Console.WriteLine($"\nFirst Cheap Product (Hybrid): {firstCheapProduct}");
}
else
{
Console.WriteLine("\nNo cheap product found (Hybrid).");
}ุฃููู ุทุฑููุฉ ุฃุณุชุฎุฏู ูุงุ
- ุงูุฃู ุฑ ุจูุฑุฌุน ููุชูุถูู ุงูุดุฎุตู ูุงูู ููู.
- ุงูู Fluent Syntax: ุฃูุซุฑ ููุฉ ูุดู
ูููุฉ (ูู ุงูู
operatorsู ุชุงุญุฉ)ุ ูู ู ุชุงุฒ ููchaining methods. - ุงูู Query Syntax: ุฃุณูู ูู ุงููุฑุงุกุฉ ูุนู
ููุงุช ุงูู
JoinูุงููGroupingุงูู ุนูุฏุฉ ุดููุฉ. - ุงูู Hybrid Syntax: ุจูุณุชุฎุฏู ู ูู ุง ูุญุชุงุฌ ูุฏู ุฌ ุจูู ุงูุทุฑููุชูู.
- ูุชูุฑ ู
ู ุงูู
ุจุฑู
ุฌูู ุจูุณุชุฎุฏู
ูุง
Fluent Syntaxูู ู ุนุธู ุงูููุชุ ูุจููุฌุฃูุง ููQuery Syntaxูู ุญุงูุงุช ุงููJoin/Groupุงูุตุนุจุฉ.
ุชุฌููุฒ ุงูุฏุงุชุง (Data Setup)
ุนุดุงู ูุจุฏุฃ ูุดุชุบู ูุนูููุง ููุฌุฑุจ ุงูู LINQ operators ุงูู
ุฎุชููุฉุ ููุญุชุงุฌ ูุนู
ู dummy project ุฃู ูุณุชุฎุฏู
classes ู lists ูููุง ุฏุงุชุง ุชุฌุฑูุจูุฉ ููุฏุฑ ูุนู
ู ุนูููุง queries. ููุณุชุฎุฏู
ุงูู Employee ู Product lists ุงููู ุนู
ููุงูู
ููู ูุฃู
ุซูุฉ.
ูุชูุงููู ููุง Data Setup for LINQ
(ูููุชุฑุถ ุฅู ุงูุฏุงุชุง ุฏู ู ูุฌูุฏุฉ ูู ุจุงูู ุงูุฃู ุซูุฉ)
Deferred Execution VS Immediate Execution
ุฏู ููุทุฉ ู
ูู
ุฉ ุฌุฏูุง ูู ููู
LINQ ุจูุดุชุบู ุฅุฒุงู.
1. Deferred Execution (ุงูุชูููุฐ ุงูู ุคุฌู)
- ู
ุนุธู
LINQ operators(ุฒูWhere,Select,OrderBy,GroupBy,Join, ูุบูุฑูุง ูุชูุฑ) ู ุด ุจุชุชููุฐ ุฃูู ู ุง ุชูุชุจูุง. - ูู
ุง ุจุชูุชุจ
queryุจุงุณุชุฎุฏุงู ุงููoperatorsุฏูุ ุงููู ุจูุญุตู ุฅูLINQุจูุณุฌู ุงูุฎุทูุงุช ุฃู ุงููexpressionุจุชุงุน ุงููqueryุฏูุ ูุจูุฏููู ูุฃููุง โูุนุฏโ (Promise) ุฃู ูุตูุฉ ููุชูููุฐ. - ุงูู
Queryู ุด ุจูุชููุฐ ูุนูููุง ุฅูุง ูู ุง ุชูุฌู ุชุทูุจ ุงููุชูุฌุฉ ุจุชุงุนุชู. ุฅู ุชู ุจูุทูุจ ุงููุชูุฌุฉุ- ูู
ุง ูุนู
ู
loopุนูู ุงููresultุจุงุณุชุฎุฏุงูforeach. - ูู
ุง ููุงุฏู ุนูู
methodู ู ุงููู ุจุชุนู ูImmediate Execution(ุฒูToList(),ToArray(),Count(),First(),Sum(), etc.).
- ูู
ุง ูุนู
ู
- ุนูู ู
ุณุชูู ุงูู
Memoryุ ุงููvariableุงููู ุจูุดูู ูุชูุฌุฉ ุงููdeferred query(ุฒูevenNumbersูู ุงูู ุซุงู ุชุญุช) ุจูุฎุฒู ุจุณ ุงููุตูุฉ ุจุชุงุนุฉ ุงููqueryูุจูุญุชูุธ ุจูreferenceูููoriginal list(ุฒูnumbers). - ูู
ุง ุชูุฌู ุชุทูุจ ุงููุชูุฌุฉ (ู
ุซููุง ุจู
foreach)ุ ุณุงุนุชูุง ุจุณ ุงููqueryุจูุฑูุญ ูุชููุฐ ุนูู ุงููoriginal listูู ุงูููุช ุฏู ุจุญุงูุชูุง ุงูุญุงููุฉ.
ู ุซุงู ููุถุญ ุงูู Deferred Execution:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Define the query using Where (Deferred Execution operator)
var evenNumbersQuery = numbers.Where(n => n % 2 == 0);
// <<< Query is NOT executed yet! 'evenNumbersQuery' only holds the definition. >>>
Console.WriteLine("Modifying the list AFTER defining the query...");
numbers.Add(12); // Add a new even number
numbers.Add(14); // Add another new even number
numbers.Remove(4); // Remove an existing even number
Console.WriteLine("Iterating through the query result (Execution happens NOW):");
// The query executes here because we are asking for the results via foreach
foreach (var item in evenNumbersQuery)
{
Console.Write(item + " "); // Output will include 12, 14 and exclude 4
}
Console.WriteLine();
// Expected output: 2 6 8 10 12 14ููู ุงูู LINQ ุจุชุดุชุบู ุจุงูุทุฑููุฉ ุงูู ุคุฌูุฉ ุฏูุ ุฅูู ููุงูุฏูุงุ
- ุงูู Performance (ุงูุฃุฏุงุก):
- ุงูู
Queryู ุด ุจูุชููุฐ ุฅูุง ูู ุง ุชุญุชุงุฌู ูุนููุง. ูู ุนุฑูุชqueryูู ุนู ูุชุด ุนูููloopุฃู ู ุญููุชููุด ููListุ ู ุด ููุณุชููู ุฃู ููุช ุชูููุฐ ุชูุฑูุจูุง. - ูู ุนูุฏู
queryุจูุฑุฌุน ุฏุงุชุง ูุชูุฑุ ูุงูุช ู ุญุชุงุฌ ุจุณ ุฃูู ุนูุตุฑ (FirstOrDefault()) ุฃู ุฃูู ูุงู ุนูุตุฑ (Take(5)), ุงููqueryููุชููุฐ ุจุณ ูุญุฏ ู ุง ูุฌูุจ ุงูู ุทููุจ ูู ุด ูููู ู ุจุงูู ุงูุฏุงุชุง.
- ุงูู
- ุงูู Memory Efficiency (ููุงุกุฉ ุงูุฐุงูุฑุฉ):
- ุงููุชุงุฆุฌ ู
ุด ุจุชุชุฎุฒู ูู ุงูู
memoryูููุง ู ุฑุฉ ูุงุญุฏุฉ (ุฅูุง ูู ุทูุจุช ุฏู ุจูToList()ู ุซููุง). ุฏู ูููุณ ุฌุฏูุง ูู ุจุชุชุนุงู ู ู ุน ุญุฌู ุฏุงุชุง ูุจูุฑ ุฌุฏูุง ู ู ูู ู ููููุด ูู ุงููmemory.
- ุงููุชุงุฆุฌ ู
ุด ุจุชุชุฎุฒู ูู ุงูู
- ุงูู Composability (ุงูุชุฑููุจ):
- ุชูุฏุฑ ุชุจูู
queryู ุนูุฏ ุนูู ู ุฑุงุญู. ู ู ูู ุชุนุฑูqueryุฃุณุงุณูุ ูุจุนุฏูู ุชุถูู ุนูููfilterุชุงูู (.Where(...)) ุฃู ุชุฑุชูุจ (.OrderBy(...)) ุญุณุจ ุงูุญุงุฌุฉุ ููู ุฏู ููุชุฌู ุน ูููุชุฑูุจ ู ุน ุจุนุถ ููุชููุฐ ู ุฑุฉ ูุงุญุฏุฉ ูู ุงูุขุฎุฑ.
- ุชูุฏุฑ ุชุจูู
- ุงูู Always Fresh Data (ุฏุงูู
ูุง ุฃุญุฏุซ ุฏุงุชุง):
- ุฒู ู
ุง ุดููุง ูู ุงูู
ุซุงูุ ูุฅู ุงูู
queryุจูุชููุฐ ูู ุง ุชุทูุจ ุงููุชูุฌุฉุ ููู ุฏุงูู ูุง ุจูุดุชุบู ุนูู ุขุฎุฑ ูุณุฎุฉ ู ู ุงูุฏุงุชุง ุงููู ูู ุงููsource list. ูู ุนุฏูุช ูู ุงููlistุจุนุฏ ู ุง ุนุฑูุช ุงููqueryููุจู ู ุง ุชููุฐูุ ุงูุชุนุฏููุงุช ุฏู ูุชูุนูุณ ูู ุงููุชูุฌุฉ.
- ุฒู ู
ุง ุดููุง ูู ุงูู
ุซุงูุ ูุฅู ุงูู
- ุงูู Working with potentially infinite sequences:
- ูุธุฑููุงุ ู
ู
ูู ุชุนู
ู
queryุนููsequenceู ุด ุจุชูุชูู (ู ุซููุงgenerator functionุจุชุทูุน ุฃุฑูุงู ููุฃุจุฏ)ุ ูุชุงุฎุฏ ู ููุง ุฌุฒุก (Take(100)) ู ู ุบูุฑ ู ุง ุชุญุชุงุฌ ุชุญู ู ุงููsequenceูููุง.
- ูุธุฑููุงุ ู
ู
ูู ุชุนู
ู
ุงูู Categories ุงููู ุจุชุดุชุบู Deferred Execution:
ู
ุนุธู
ุงูู Categories (ุญูุงูู 10 ู
ู ุงูู 13) ุจุชุดุชุบู ุจุงูุทุฑููุฉ ุฏูุ ุฒู:
- Filtration (
Where) - Projection (
Select,SelectMany) - Ordering (
OrderBy,ThenBy,Reverse) - Grouping (
GroupBy) - Joining (
Join,GroupJoin) - Set (
Union,Intersect,Except,Distinct,Concat) - Partitioning (
Take,Skip,TakeWhile,SkipWhile,Chunk) - Generation (
Range,Repeat,Empty) - Zipping (
Zip)
2. Immediate Execution (ุงูุชูููุฐ ุงูููุฑู)
- ุนูู ุนูุณ ุงูู
Deferredุ ููู ุจุนุถ ุงููLINQ operatorsุจุชููุฐ ุงููqueryููุฑูุง ุฃูู ู ุง ุชูุงุฏู ุนูููุง. - ุงูู
Operatorsุฏู ุบุงูุจูุง ุจุชููู ุงููู:- ุจุชุฑุฌุน ููู
ุฉ ูุงุญุฏุฉ (single value) ู
ู ุงูู
sequence(ุฒูCount(),Sum(),Max(),First(),ElementAt()). - ุจุชุญูู ุงูู
sequenceูู collection ุชุงููุฉ ูู ุงููmemory(ุฒูToList(),ToArray(),ToDictionary(),ToHashSet()).
- ุจุชุฑุฌุน ููู
ุฉ ูุงุญุฏุฉ (single value) ู
ู ุงูู
- ูู
ุง ุจุชุณุชุฎุฏู
ูุงุญุฏ ู
ู ุงูู
operatorsุฏูุ ุงููqueryุงููู ูุจูู (ูู ููู) ุจูุชููุฐ ููู ุนูุทููุ ูุงููุชูุฌุฉ ุจุชุชุญุณุจ ูุชุชุฎุฒู ุฃู ุชุชุฑุฌุน.
ู ุซุงู ููุถุญ ุงูู Immediate Execution:
List<int> numbers2 = new List<int> { 1, 2, 3, 4, 5 };
// Define the query AND execute it immediately using ToList()
List<int> evenNumbersList = numbers2.Where(n => n % 2 == 0).ToList();
// <<< Query executed NOW! 'evenNumbersList' holds [2, 4] in memory. >>>
Console.WriteLine("\nModifying the list AFTER immediate execution...");
numbers2.Add(6); // Add a new even number
numbers2.Add(8); // Add another new even number
Console.WriteLine("Iterating through the immediate result list:");
// We are iterating through the list created earlier, not re-executing the query
foreach (var item in evenNumbersList)
{
Console.Write(item + " "); // Output will only be the numbers captured initially
}
Console.WriteLine();
// Expected output: 2 4ุงููุฑู ุจูู ุงูู Deferred ูุงูู Immediate ุจุงุฎุชุตุงุฑ:
- ุงูู Deferred:
- ุงูุชูููุฐ ุจูุชุฃุฌู ูุญุฏ ู
ุง ุชุทูุจ ุงููุชูุฌุฉ (
foreach,ToList(), etc.). - ุงููุชูุฌุฉ ุฏุงูู ูุง ุจุชุนูุณ ุขุฎุฑ ุญุงูุฉ ููุฏุงุชุง.
- ุฃู
ุซูุฉ:
Where(),Select(),OrderBy().
- ุงูุชูููุฐ ุจูุชุฃุฌู ูุญุฏ ู
ุง ุชุทูุจ ุงููุชูุฌุฉ (
- ุงูู Immediate:
- ุงูุชูููุฐ ุจูุญุตู ููุฑูุง ุฃูู ู
ุง ุชูุงุฏู ุงูู
operator. - ุงููุชูุฌุฉ ุจุชุชุญุณุจ ูุชุชุฎุฒู (ูู
ToListู ุซููุง) ุฃู ุชุชุฑุฌุน (ููCountู ุซููุง). - ุฃู ุชุนุฏููุงุช ุนูู ุงูุฏุงุชุง ุงูุฃุตููุฉ ุจุนุฏ ุงูุชูููุฐ ู ุด ุจุชุฃุซุฑ ุนูู ุงููุชูุฌุฉ ุงููู ุงุชุญุณุจุช ุฎูุงุต.
- ุฃู
ุซูุฉ:
ToList(),ToArray(),Count(),First(),Sum().
- ุงูุชูููุฐ ุจูุญุตู ููุฑูุง ุฃูู ู
ุง ุชูุงุฏู ุงูู
ุฅู ุชู ูุณุชุฎุฏู ุงูู Immediate Executionุ
- ูู
ุง ุชููู ุนุงูุฒ ุชุญูุธ โููุทุฉโ (snapshot) ู
ู ูุชูุฌุฉ ุงูู
queryูู ูุญุธุฉ ู ุนููุฉุ ูู ุด ุนุงูุฒูุง ุชุชุฃุซุฑ ุจุฃู ุชุบููุฑุงุช ูุชุญุตู ุจุนุฏ ูุฏู ูู ุงูุฏุงุชุง ุงูุฃุตููุฉ. - ูู
ุง ุชููู ูุชุณุชุฎุฏู
ูุชูุฌุฉ ุงูู
queryุฏู ูุฐุง ู ุฑุฉ ูู ุงูููุฏ ุจุชุงุนูุ ูุชุญููููุง ููListุฃูArrayู ุฑุฉ ูุงุญุฏุฉ ู ู ูู ูููู ุฃููุฃ ู ู ุฅุนุงุฏุฉ ุชูููุฐ ุงููqueryูู ู ุฑุฉ. - ูู
ุง ุชููู ุงููุชูุฌุฉ ุงูููุงุฆูุฉ ููู
queryูู ููู ุฉ ูุงุญุฏุฉ (ุฒู ุนุฏุฏ ุงูุนูุงุตุฑ ุฃู ู ุฌู ูุนูู ).
ุงูู Categories ุงููู ุจุชุดุชุบู Immediate Execution:
ููู 3 Categories ุฃุณุงุณูุฉ ุจุชุดุชุบู ุจุงูุทุฑููุฉ ุฏู:
- ุงูู Element Operators ุงููู ุจุชุฌูุจ ุนูุตุฑ ูุงุญุฏ (ุฒู
First,Last,Single,ElementAtูู ุดุชูุงุชูู ). - ุงููAggregate Operator ุงููู ุจุชุนู
ู ุนู
ููุงุช ุญุณุงุจูุฉ ุฃู ุชุฌู
ูุนูุฉ ุนูู ูู ุงูู
sequenceุนุดุงู ุชุฑุฌุน ููู ุฉ ูุงุญุฏุฉ (ุฒูCount,Sum,Average,Min,Max,Aggregate,Any,All). - ุงููCasting Operators ุงููู ุจุชุญูู ุงูู
sequenceูููุนcollectionุชุงูู (ุฒูToList,ToArray,ToDictionary,ToLookup,ToHashSet).
ู
ูุญูุธุฉ: ูู ุนุงูุฒ ุชุฌุจุฑ query ู
ุนู
ูู ุจู deferred operators ุฅูู ูุชููุฐ ููุฑูุงุ ู
ู
ูู ุชุถูู ูู ุขุฎุฑู operator ู
ู ุจุชูุน ุงูู immediate execution (ุฒู .ToList()).
LINQ (LINQ Operations / Operators)
ุฒู ู
ุง ูููุงุ LINQ ููู ุฃูุชุฑ ู
ู 40 operator ู
ุชูุณู
ูู ูู 13 category. ุงุชููู
ูุง ููู ุนู ุฃูู category ุงููู ูู ุงูู Filtration Operators ููุงู ุฃูู
ูุงุญุฏ ููู ูู Where.
ููุงุฎุฏ ุฏูููุชู ุจุงูู ุงูู categories ุงูู
ุดููุฑุฉ ูุงูู
ูู
ุฉ:
1. Projection or Transformation Operators (ุชุญููู ุงูุดูู)
ุงูู Operators ุฏู ุจุชุงุฎุฏ ูู ุนูุตุฑ ูู ุงูู sequence ุงูุฃุตููุฉ ูุชุญููู ูุดูู ุชุงูู ุฃู ุชุฎุชุงุฑ ุฌุฒุก ู
ูู. ุฃุดูุฑูู
Select ู SelectMany. (ุฏูู Deferred Execution).
Select()
- ุจุชุงุฎุฏ ูู ุนูุตุฑ ูู ุงูู
collectionูุชุญููู ูุญุงุฌุฉ ุชุงููุฉ (ู ู ูู ุชูููpropertyู ุนููุฉ ู ู ุงูุนูุตุฑุ ุฃูobjectุฌุฏูุฏ ุฎุงูุต). - ุจุชุฑุฌุน
sequenceุฌุฏูุฏุฉ ุจููุณ ุญุฌู ุงููsequenceุงูุฃุตููุฉุ ุจุณ ุงูุนูุงุตุฑ ุงููู ุฌูุงูุง ุดูููุง ู ุชุบูุฑ.
ู ุซุงู: ุงุฎุชูุงุฑ ุฃุณู ุงุก ุงูู ูุธููู ุจุณ:
// Select just the names of the employees
var employeeNames = employees.Select(employee => employee.Name);
// employeeNames is now an IEnumerable<string>
Console.WriteLine("\nEmployee Names (Select):");
foreach (var name in employeeNames)
{
Console.WriteLine(name);
}
// Query Syntax equivalent:
var employeeNamesQuery = from e in employees
select e.Name;ู ุซุงู: ุงุฎุชูุงุฑ ุฃูุชุฑ ู ู property (ุจุงุณุชุฎุฏุงู Anonymous Type):
ู
ูููุนุด ุฃุฑุฌุน ุฃูุชุฑ ู
ู property ู
ุจุงุดุฑุฉ ุจู Select. ูู ุนุงูุฒ ุฃุฑุฌุน ู
ุซููุง ุงุณู
ูุนู
ุฑ ุงูู
ูุธูุ ูุงุฒู
ุฃุฑุฌุนูู
ูู object ุฌุฏูุฏ.
ุงูุญู ุงูุณูู ูุงูู ุจุงุดุฑ ููุง ูู ุงุณุชุฎุฏุงู Anonymous Type:
// Select Name and Age into an Anonymous Type
var nameAndAge = employees.Select(e => new { EmployeeName = e.Name, EmployeeAge = e.Salary }); // Assuming Salary represents Age for example
// nameAndAge is now an IEnumerable of objects with Name and Age properties
Console.WriteLine("\nEmployee Name and Age (Select with Anonymous Type):");
foreach (var item in nameAndAge)
{
Console.WriteLine($"Name: {item.EmployeeName}, Age: {item.EmployeeAge}");
// You can access properties by the names you gave them (EmployeeName, EmployeeAge)
}
// Using aliases for shorter names in the anonymous type:
var nameAndAgeShorter = employees.Select(e => new { N = e.Name, A = e.Salary });
foreach (var item in nameAndAgeShorter)
{
Console.WriteLine($"N: {item.N}, A: {item.A}");
}
// Query Syntax equivalent for Anonymous Type:
var nameAndAgeQuery = from e in employees
select new // Create anonymous type
{
EmployeeName = e.Name,
EmployeeAge = e.Salary
};- ุงูู
Anonymous Typeุฏูtypeู ููุด ุงุณู ุจูุนุฑูู ูู ุงูููุฏุ ุงููCLRูู ุงููู ุจูุนู ูู ูู ุงููruntime. - ูู ุนุงูุฒ ุชุนู
ู
assignููvariableูููanonymous typeููvariableุชุงููุ ูุงุฒู ุงููpropertiesุชููู ุจููุณ ุงูุฃุณู ุงุก ูุงููtypesูุงูุชุฑุชูุจ ุจุงูุธุจุท.
Indexed Select:
ุฒู ุงูู Indexed Whereุ ููู overload ูู Select ุจูุงุฎุฏ ุงูู index ูู parameter ุชุงูู. ู
ุชุงุญ ุจุณ ูู ุงูู Fluent Syntax.
// Select Name along with its index in the original list
var namesWithIndex = employees.Select((emp, index) => new { Index = index, Name = emp.Name });
Console.WriteLine("\nNames with Index (Indexed Select):");
foreach (var item in namesWithIndex)
{
Console.WriteLine($"Index: {item.Index}, Name: {item.Name}");
}SelectMany()
- ุฏู ุจูุณุชุฎุฏู
ูุง ูู
ุง ูููู ุนูุฏูุง
sequence of sequences(ูุนูู ู ุซููุงListุฌูุงูุงListุชุงููุฉ) ูุนุงูุฒูู ูุนู ููุง โูุฑุฏโ ุฃู โุชุณุทูุญโ (Flattening) ุนุดุงู ุชุจููsequenceูุงุญุฏุฉ ุจุณ. - ุชุฎูู ุนูุฏู ููุณุชุฉ ู
ูุธูููุ ููู ู
ูุธู ุนูุฏู ููุณุชุฉ ุจุงูู
ูุงุฑุงุช (
Skills) ุจุชุงุนุชู. ูู ุนุงูุฒ ุชุฌูุจ ูู ุงูู ูุงุฑุงุช ุงูู ูุฌูุฏุฉ ุนูุฏ ูู ุงูู ูุธููู ูู ููุณุชุฉ ูุงุญุฏุฉุ ููุง ุจูุณุชุฎุฏูSelectMany.
ู ุซุงู:
// Assume Employee class has a List<string> Skills property
public class EmployeeWithSkills
{
public int Id { get; set; }
public string Name { get; set; }
public List<string> Skills { get; set; }
public override string ToString() => $"Id: {Id}, Name: {Name}, Skills: {string.Join(", ", Skills)}";
}
List<EmployeeWithSkills> employeesWithSkills = new List<EmployeeWithSkills>
{
new EmployeeWithSkills { Id = 1, Name = "Ahmed", Skills = new List<string> { "C#", "SQL", "ASP.NET" } },
new EmployeeWithSkills { Id = 2, Name = "Mona", Skills = new List<string> { "HTML", "CSS", "JavaScript" } },
new EmployeeWithSkills { Id = 3, Name = "Ali", Skills = new List<string> { "C#", "Azure", "Docker" } },
new EmployeeWithSkills { Id = 4, Name = "Sara", Skills = new List<string> { "JavaScript", "React", "Node.js" } }
};
// Using SelectMany to get a single list of all skills
var allSkills = employeesWithSkills.SelectMany(emp => emp.Skills);
// allSkills is now IEnumerable<string> containing all skills from all employees
Console.WriteLine("\nAll Skills (SelectMany):");
Console.WriteLine(string.Join(", ", allSkills));
// Output: C#, SQL, ASP.NET, HTML, CSS, JavaScript, C#, Azure, Docker, JavaScript, React, Node.js
// If you want only unique skills, combine SelectMany with Distinct
var uniqueSkills = employeesWithSkills.SelectMany(emp => emp.Skills).Distinct();
Console.WriteLine("\nUnique Skills (SelectMany + Distinct):");
Console.WriteLine(string.Join(", ", uniqueSkills));
// Output: C#, SQL, ASP.NET, HTML, CSS, JavaScript, Azure, Docker, React, Node.js
// Query Syntax equivalent for SelectMany:
// Uses multiple 'from' clauses
var allSkillsQuery = from emp in employeesWithSkills // Outer loop for employees
from skill in emp.Skills // Inner loop for skills within each employee
select skill; // Select the skill
Console.WriteLine("\nAll Skills (Query Syntax):");
Console.WriteLine(string.Join(", ", allSkillsQuery));
var uniqueSkillsQuery = (from emp in employeesWithSkills
from skill in emp.Skills
select skill).Distinct(); // Add Distinct for unique
Console.WriteLine("\nUnique Skills (Query Syntax + Distinct):");
Console.WriteLine(string.Join(", ", uniqueSkillsQuery));
ุงููุฑู ุจูู Select ู SelectMany ูู ุงูุญุงูุฉ ุฏู:
ูู ููุช ุงุณุชุฎุฏู
ุช Select ุจุฏู SelectMany ูู ุงูู
ุซุงู ุจุชุงุน ุงูู
ูุงุฑุงุช:
var skillsUsingSelect = employeesWithSkills.Select(emp => emp.Skills);
// skillsUsingSelect is IEnumerable<List<string>> (a list of lists)
Console.WriteLine("\nSkills using Select (Incorrect for flattening):");
foreach (var skillList in skillsUsingSelect)
{
// This will print the default ToString() of List<string>, not the skills themselves
Console.WriteLine(skillList);
// Example output line: System.Collections.Generic.List`1[System.String]
}ุงููSelect ูุชุฑุฌุนูู sequence ู
ู ููุน List<string> (ููุณุชุฉ ุงูููุณุชุงุช)ุ ู
ุด ููุณุชุฉ ูุงุญุฏุฉ ูููุง ูู ุงูู strings. ุนุดุงู ูุฏู SelectMany ูู ุงูู
ูุงุณุจุฉ ูู ุญุงูุฉ ุงูู Flattening.
2. Ordering Operators (ุชุฑุชูุจ ุงูุนูุงุตุฑ)
ุงูู Operators ุฏู ุจูุณุชุฎุฏู
ูุง ุนุดุงู ูุฑุชุจ ุนูุงุตุฑ ุงูู sequence ุจูุงุกู ุนูู property ู
ุนููุฉ ุฃู ุฃูุชุฑ. (ุฏูู Deferred Execution).
OrderBy()
- ุจุชุฑุชุจ ุงูุนูุงุตุฑ ุชุตุงุนุฏููุง (Ascending) (ู
ู ุงูุตุบูุฑ ูููุจูุฑุ ุฃู ุฃุจุฌุฏููุง ููู
strings).
// Order employees by Salary (ascending)
var sortedBySalaryAsc = employees.OrderBy(emp => emp.Salary);
Console.WriteLine("\nEmployees Sorted by Salary (Ascending):");
foreach (var emp in sortedBySalaryAsc)
{
Console.WriteLine(emp);
}
// Query Syntax equivalent:
var sortedBySalaryAscQuery = from e in employees
orderby e.Salary // 'ascending' is the default
select e;OrderByDescending()
- ุจุชุฑุชุจ ุงูุนูุงุตุฑ ุชูุงุฒูููุง (Descending) (ู ู ุงููุจูุฑ ููุตุบูุฑ).
// Order employees by Salary (descending)
var sortedBySalaryDesc = employees.OrderByDescending(emp => emp.Salary);
Console.WriteLine("\nEmployees Sorted by Salary (Descending):");
foreach (var emp in sortedBySalaryDesc)
{
Console.WriteLine(emp);
}
// Query Syntax equivalent:
var sortedBySalaryDescQuery = from e in employees
orderby e.Salary descending
select e;ThenBy() / ThenByDescending()
- ุจูุณุชุฎุฏู
ูู
ุจุนุฏ
OrderByุฃูOrderByDescendingุนุดุงู ูุนู ู ุชุฑุชูุจ ุซุงููู (secondary sort). - ูุนูู ูู ููู ุนูุตุฑูู ูููู
ููุณ ุงูููู
ุฉ ูู ุงูุชุฑุชูุจ ุงูุฃูู (ู
ุซููุง ุงุชููู ู
ูุธููู ูููู
ููุณ ุงูู
ุฑุชุจ)ุ ูุณุชุฎุฏู
ThenByุนุดุงู ูุฑุชุจูู ุชุงูู ุจูุงุกู ุนููpropertyุชุงููุฉ (ู ุซููุง ูุฑุชุจูู ุฃุจุฌุฏููุง ุจุงูุงุณู ).
// Order by Gender (asc), then by Name (asc) for those with the same gender
var sortedByGenderThenName = employees
.OrderBy(emp => emp.Gender)
.ThenBy(emp => emp.Name);
Console.WriteLine("\nEmployees Sorted by Gender (Asc) then Name (Asc):");
foreach (var emp in sortedByGenderThenName)
{
Console.WriteLine(emp);
}
// You can also use ThenByDescending
var sortedBySalaryDescThenNameAsc = employees
.OrderByDescending(emp => emp.Salary) // Highest salary first
.ThenBy(emp => emp.Name); // If salaries are equal, sort by name A-Z
// Query Syntax equivalent (comma separates the sorting criteria):
var sortedQuery = from e in employees
orderby e.Gender, e.Name // Primary sort by Gender, Secondary by Name
select e;
var sortedQuery2 = from e in employees
orderby e.Salary descending, e.Name ascending // Can mix ascending/descending
select e;
Reverse()
- ุฏู ู
ุด ุจุชุนู
ู
sortุจู ุนูู ุงูููู ุฉุ ูู ุจุณ ุจุชุนูุณ ุชุฑุชูุจ ุงูุนูุงุตุฑ ูู ุงููsequenceุฒู ู ุง ูู.
// Reverse the original order of the list
// Note: Reverse() modifies the list in-place if it's a List<T>,
// but the LINQ Reverse() extension method returns a new reversed IEnumerable
// without modifying the original source IF the source is not a List/Array.
// For safety, let's apply it to a query result or a copy if needed.
var reversedOrder = employees.AsEnumerable().Reverse(); // Apply to IEnumerable view
Console.WriteLine("\nEmployees in Reversed Original Order:");
foreach (var emp in reversedOrder)
{
Console.WriteLine(emp);
}
// Note: Query Syntax does not have a direct equivalent for Reverse().3. Element Operators (ุงุฎุชูุงุฑ ุนูุตุฑ ู ุญุฏุฏ)
ุงูู Operators ุฏู ุจูุณุชุฎุฏู
ูุง ุนุดุงู ูุฌูุจ ุนูุตุฑ ูุงุญุฏ ุจุณ ู
ู ุงูู sequence ุจูุงุกู ุนูู ู
ููุนู ุฃู ุดุฑุท ู
ุนูู.
- ู
ูู
ุฌุฏูุง: ูู ุงูู
Operatorsูู ุงููCategoryุฏู ุจุชุนู ู Immediate Execution (ุชูููุฐ ููุฑู). - ู ูู ุฌุฏูุง: ู ุนุธู ูู ู ุชุงุญูู ุจุณ ูู Fluent Syntax (ุฃู ู ู ูู ุชุณุชุฎุฏู Hybrid Syntax).
ุงูู Operators ุงูุฃุณุงุณูุฉ ูู ูุงุฑูุชูุง:
| Operator | ุงููุตู | ูู ุงูู Sequence ูุงุถูุฉุ | ูู ููู ุฃูุชุฑ ู ู ุนูุตุฑ ุจูุญูู ุงูุดุฑุทุ | ูู ู ููุด ููุง ุนูุตุฑ ุจูุญูู ุงูุดุฑุทุ |
|---|---|---|---|---|
First() | ุจูุฑุฌุน ุฃูู ุนูุตุฑ. | Exception | ุจูุฑุฌุน ุฃูู ูุงุญุฏ ููุงุจูู | Exception (ูู ููู ุดุฑุท) |
FirstOrDefault() | ุจูุฑุฌุน ุฃูู ุนูุตุฑุ ุฃู ุงูููู
ุฉ ุงูุงูุชุฑุงุถูุฉ (null ููู reference typesุ 0 ููู intุ false ููู boolโฆ). | ุจูุฑุฌุน Default | ุจูุฑุฌุน ุฃูู ูุงุญุฏ ููุงุจูู | ุจูุฑุฌุน Default (ูู ููู ุดุฑุท) |
Last() | ุจูุฑุฌุน ุขุฎุฑ ุนูุตุฑ. | Exception | ุจูุฑุฌุน ุขุฎุฑ ูุงุญุฏ ููุงุจูู | Exception (ูู ููู ุดุฑุท) |
LastOrDefault() | ุจูุฑุฌุน ุขุฎุฑ ุนูุตุฑุ ุฃู ุงูููู ุฉ ุงูุงูุชุฑุงุถูุฉ. | ุจูุฑุฌุน Default | ุจูุฑุฌุน ุขุฎุฑ ูุงุญุฏ ููุงุจูู | ุจูุฑุฌุน Default (ูู ููู ุดุฑุท) |
Single() | ุจูุฑุฌุน ุงูุนูุตุฑ ุงููุญูุฏ. | Exception | Exception | Exception |
SingleOrDefault() | ุจูุฑุฌุน ุงูุนูุตุฑ ุงููุญูุฏุ ุฃู ุงูููู ุฉ ุงูุงูุชุฑุงุถูุฉ ูู ูุงุถูุฉ. | ุจูุฑุฌุน Default | Exception | ุจูุฑุฌุน Default |
ElementAt(index) | ุจูุฑุฌุน ุงูุนูุตุฑ ุนูุฏ ููุฑุณ (index) ู ุนูู (ุจูุจุฏุฃ ู ู 0). | Exception (ูู index ุบูุท) | N/A | Exception (ูู index ุบูุท) |
ElementAtOrDefault(index) | ุจูุฑุฌุน ุงูุนูุตุฑ ุนูุฏ ููุฑุณ (index) ู ุนููุ ุฃู ุงูููู ุฉ ุงูุงูุชุฑุงุถูุฉ ูู ุงูู index ุบูุท (ุฎุงุฑุฌ ุงููุทุงู). | ุจูุฑุฌุน Default (ูู index ุบูุท) | N/A | ุจูุฑุฌุน Default (ูู index ุบูุท) |
ุฃู ุซูุฉ:
- ูู
operatorู ู ุฏูู (ู ุง ุนุฏุงElementAt/OrDefault) ูููoverloadุชุงูู ุจูุงุฎุฏpredicate(ุดุฑุท) ุนุดุงู ููุงูู ุฃูู/ุขุฎุฑ/ูุญูุฏ ุนูุตุฑ ุจูุญูู ุงูุดุฑุท ุฏู. - ุงูู
OrDefaultversions (ุฒูFirstOrDefault,LastOrDefault,SingleOrDefault,ElementAtOrDefault) ููููoverloadุชุงูู (ูู ุจุนุถ ุงูู versions ุงูุฌุฏูุฏุฉ ู ู .NET) ุจูุณู ุญูู ุชุญุฏุฏ ุงูููู ุฉ ุงููdefaultุงููู ุชุฑุฌุน ุจุฏู ุงููdefaultุจุชุงุน ุงููtype.
Console.WriteLine("\n--- Element Operators ---");
// First
try
{
var firstEmployee = employees.First(); // Gets the first employee (Ahmed)
Console.WriteLine($"First Employee: {firstEmployee.Name}");
var firstFemale = employees.First(e => e.Gender == "Female"); // Gets the first female (Mona)
Console.WriteLine($"First Female Employee: {firstFemale.Name}");
// var nonExistent = employees.First(e => e.Salary > 10000); // Throws Exception
}
catch (Exception ex) { Console.WriteLine($"First() Exception: {ex.Message}"); }
// FirstOrDefault
var firstEmpOrDefault = employees.FirstOrDefault(); // Gets Ahmed
Console.WriteLine($"FirstOrDefault Employee: {firstEmpOrDefault?.Name}");
var firstFemaleOrDefault = employees.FirstOrDefault(e => e.Gender == "Female"); // Gets Mona
Console.WriteLine($"FirstOrDefault Female: {firstFemaleOrDefault?.Name}");
var nonExistentOrDefault = employees.FirstOrDefault(e => e.Salary > 10000); // Returns null
Console.WriteLine($"FirstOrDefault NonExistent (>10k Salary): {nonExistentOrDefault?.Name ?? "null"}");
// Example with custom default (might require newer .NET or specific package)
// var customDefault = employees.FirstOrDefault(e => e.Salary > 10000, new Employee { Name = "Default Emp" });
// Last
try
{
var lastEmployee = employees.Last(); // Gets the last employee added (depends on list init)
Console.WriteLine($"Last Employee: {lastEmployee.Name}");
var lastMale = employees.Last(e => e.Gender == "Male"); // Gets the last male (Ali)
Console.WriteLine($"Last Male Employee: {lastMale.Name}");
}
catch (Exception ex) { Console.WriteLine($"Last() Exception: {ex.Message}"); }
// LastOrDefault
var lastOrDefaultEmp = employees.LastOrDefault();
Console.WriteLine($"LastOrDefault Employee: {lastOrDefaultEmp?.Name}");
var lastOrDefaultNonExistent = employees.LastOrDefault(e => e.Address == "Mars"); // Returns null
Console.WriteLine($"LastOrDefault NonExistent (Mars): {lastOrDefaultNonExistent?.Name ?? "null"}");
// Single (Use when you expect EXACTLY ONE result)
try
{
// var singleEmp = employees.Single(); // Throws Exception (more than one employee)
var singleAli = employees.Single(e => e.Name == "Ali"); // Gets Ali (assuming name is unique)
Console.WriteLine($"Single Employee (Ali): {singleAli.Name}");
// var singleFemale = employees.Single(e => e.Gender == "Female"); // Throws Exception (more than one female)
// var singleNonExistent = employees.Single(e => e.Salary > 10000); // Throws Exception (none found)
}
catch (Exception ex) { Console.WriteLine($"Single() Exception: {ex.Message}"); }
// SingleOrDefault (Use when you expect ZERO or ONE result)
try
{
// var singleOrDefaultEmp = employees.SingleOrDefault(); // Throws Exception (more than one employee)
var singleOrDefaultAli = employees.SingleOrDefault(e => e.Name == "Ali"); // Gets Ali
Console.WriteLine($"SingleOrDefault Employee (Ali): {singleOrDefaultAli?.Name}");
var singleOrDefaultNonExistent = employees.SingleOrDefault(e => e.Salary > 10000); // Returns null (zero found)
Console.WriteLine($"SingleOrDefault NonExistent (>10k Salary): {singleOrDefaultNonExistent?.Name ?? "null"}");
// var singleOrDefaultFemale = employees.SingleOrDefault(e => e.Gender == "Female"); // Throws Exception (more than one female)
}
catch (Exception ex) { Console.WriteLine($"SingleOrDefault() Exception: {ex.Message}"); }
// ElementAt
try
{
var secondEmployee = employees.ElementAt(1); // Gets the employee at index 1 (Mona)
Console.WriteLine($"ElementAt(1): {secondEmployee.Name}");
// var outOfBounds = employees.ElementAt(100); // Throws Exception
}
catch (Exception ex) { Console.WriteLine($"ElementAt() Exception: {ex.Message}"); }
// ElementAtOrDefault
var secondEmpOrDefault = employees.ElementAtOrDefault(1); // Gets Mona
Console.WriteLine($"ElementAtOrDefault(1): {secondEmpOrDefault?.Name}");
var outOfBoundsOrDefault = employees.ElementAtOrDefault(100); // Returns null
Console.WriteLine($"ElementAtOrDefault(100): {outOfBoundsOrDefault?.Name ?? "null"}");4. Aggregate Operators (ุชุฌู ูุน ูุญุณุงุจ)
ุงูู Operators ุฏู ุจุชุดุชุบู ุนูู ุงูู sequence ูููุง ุนุดุงู ุชุฑุฌุน ููู
ุฉ ูุงุญุฏุฉ ููุชูุฌุฉ ูุนู
ููุฉ ุญุณุงุจูุฉ ุฃู ุชุฌู
ูุนูุฉ. ุฃุดูุฑูู
7 ุชูุฑูุจูุง. (ุฏูู Immediate Execution).
| Operator | ุงููุตู |
|---|---|
Sum() | ุจูุฑุฌุน ู ุฌู ูุน ููู ุฑูู ูุฉ ูู ุงูู sequence. |
Min() | ุจูุฑุฌุน ุฃูู ููู ุฉ ูู ุงูู sequence. |
Max() | ุจูุฑุฌุน ุฃุนูู ููู ุฉ ูู ุงูู sequence. |
Average() | ุจูุฑุฌุน ุงูู ุชูุณุท ุงูุญุณุงุจู ูููู ุฑูู ูุฉ. |
Count() | ุจูุฑุฌุน ุนุฏุฏ ุงูุนูุงุตุฑ ูู ุงูู sequence. |
LongCount() | ุฒู Count ุจุณ ุจูุฑุฌุน long (ูู ุงูุนุฏุฏ ูุจูุฑ ุฃูู). |
Aggregate() | ุจูุนู ู ุนู ููุฉ ุชุฌู ูุนูุฉ ู ุฎุตุตุฉ ุฃูุช ุจุชุนุฑููุง (ุฒู ุชุฌู ูุน string ุฃู ุนู ููุฉ ุญุณุงุจูุฉ ู ุนูุฏุฉ). |
MaxBy() | (.NET 6+) ุจูุฑุฌุน ุงูุนูุตุฑ ููุณู ุงููู ููู ุฃุนูู ููู ุฉ ูู property ู ุนููุฉ. |
MinBy() | (.NET 6+) ุจูุฑุฌุน ุงูุนูุตุฑ ููุณู ุงููู ููู ุฃูู ููู ุฉ ูู property ู ุนููุฉ. |
Any() | (Boolean) ุจูุฑุฌุน true ูู ููู ุนูุตุฑ ูุงุญุฏ ุนูู ุงูุฃูู ุจูุญูู ุดุฑุท ู
ุนูู (ุฃู ูู ู
ุด ูุงุถูุฉ). |
All() | (Boolean) ุจูุฑุฌุน true ูู ูู ุงูุนูุงุตุฑ ุจุชุญูู ุดุฑุท ู
ุนูู. |
ุฃู ุซูุฉ:
Console.WriteLine("\n--- Aggregate Operators ---");
// Sum (Needs a numeric property)
var totalSalary = employees.Sum(e => e.Salary);
Console.WriteLine($"Total Salary: {totalSalary}");
// Min (Needs a comparable property)
var minSalary = employees.Min(e => e.Salary);
Console.WriteLine($"Minimum Salary: {minSalary}");
// Max
var maxSalary = employees.Max(e => e.Salary);
Console.WriteLine($"Maximum Salary: {maxSalary}");
// Average
var averageSalary = employees.Average(e => e.Salary);
Console.WriteLine($"Average Salary: {averageSalary:F2}"); // F2 for formatting
// Count
var employeeCount = employees.Count(); // Total number of employees
Console.WriteLine($"Total Employees: {employeeCount}");
var maleCount = employees.Count(e => e.Gender == "Male"); // Number of male employees
Console.WriteLine($"Male Employees: {maleCount}");
// Any (Checks for existence)
bool hasHighEarner = employees.Any(e => e.Salary > 7000); // Is there anyone earning > 7000?
Console.WriteLine($"Any employee earns > 7000? {hasHighEarner}");
bool listIsNotEmpty = employees.Any(); // Is the list not empty?
Console.WriteLine($"Is the list not empty? {listIsNotEmpty}");
// All (Checks if all elements satisfy a condition)
bool allEarnAbove3000 = employees.All(e => e.Salary > 3000); // Does everyone earn > 3000?
Console.WriteLine($"All employees earn > 3000? {allEarnAbove3000}");
// Aggregate (Example: Concatenate all names)
string allNames = employees
.Select(e => e.Name) // First select the names
.Aggregate((currentNames, nextName) => currentNames + ", " + nextName); // Aggregate them
Console.WriteLine($"All Names Concatenated: {allNames}");
// Aggregate Example: Calculate product of salaries (just for demo, not meaningful)
// Need to handle potential zero salary if calculating product
long salaryProduct = employees.Select(e => (long)e.Salary).Aggregate(1L, (acc, salary) => acc * (salary == 0 ? 1 : salary)); // Start with 1L (long)
Console.WriteLine($"Salary Product (Example): {salaryProduct}");
// MaxBy / MinBy (.NET 6+)
// Find the employee object with the highest salary
var highestEarner = employees.MaxBy(e => e.Salary);
Console.WriteLine($"Highest Earning Employee: {highestEarner?.Name} ({highestEarner?.Salary})");
// Find the employee object with the lowest salary
var lowestEarner = employees.MinBy(e => e.Salary);
Console.WriteLine($"Lowest Earning Employee: {lowestEarner?.Name} ({lowestEarner?.Salary})");
ู
ูุงุญุธุงุช ุนูู Sum, Min, Max, Average:
- ูู ุงุณุชุฎุฏู
ุชูู
ุนูู
sequenceู ูobjects(ุฒูemployees) ู ู ุบูุฑ ู ุง ุชุญุฏุฏ ุงููpropertyุงููู ููุดุชุบููุง ุนูููุง (ูุนูู ุชูููemployees.Sum()ุจุณ)ุ ุงููclassุจุชุงุน ุงููobjectุฏู (ุงููู ููEmployee) ูุงุฒู ูููู ุจูุนู ูimplementููinterfaceุฒู Cs ICompareable ุนุดุงู ุงููoperatorูุนุฑู ููุงุฑู ุฃู ูุฌู ุน ุนูู ุฃุณุงุณ ุฅูู. ุจุณ ุงูุทุฑููุฉ ุฏู ู ุด ุนู ููุฉ ูู ุด ุจูุณุชุฎุฏู ูุง ุบุงูุจูุง. - ุงูุฃุญุณู ุฏุงูู
ูุง ุฅูู ุชุญุฏุฏ ุงูู
propertyุงููู ุนุงูุฒ ุชุนู ู ุนูููุง ุงูุนู ููุฉ ุจุงุณุชุฎุฏุงูlambda expression(ุฒูemployees.Sum(e => e.Salary)). - ูููู
overloadsูุชูุฑ ุนุดุงู ูุชุนุงู ููุง ู ุน ุฃููุงุน ุฃุฑูุงู ู ุฎุชููุฉ (int,double,decimal,long,Nullable versions, etc.).
ู
ูุงุฑูุฉ Max/Min ุจู MaxBy/MinBy:
- ุงูู
Max(e => e.Salary): ุจุชุฑุฌุน ุฃุนูู ููู ุฉ ููู ุฑุชุจ ููุณูุง (ู ุซููุง 8000). - ุงูู
MaxBy(e => e.Salary): ุจุชุฑุฌุน ุงูู ูุธู ููุณู (Employee object) ุงููู ุนูุฏู ุฃุนูู ู ุฑุชุจ. - ุงูู
MaxBy/MinByู ููุฏูู ูู ุง ุชููู ุนุงูุฒ ุงููobjectููู ู ุด ุจุณ ุงูููู ุฉ. (ู ุชุงุญูู ู ู .NET 6). - ูุจู .NET 6ุ ููุง ุจูุนู
ู ููุณ ูุธููุฉ
MaxByุนู ุทุฑููOrderByDescending(...).First(). - ู
ูู
ูู EF Core:
MaxBy/MinByู ู ูู ูููููุง ูุณู ู ุด ู ุชุฑุฌู ูู ูููุณ ููSQLูู ูู ุฅุตุฏุงุฑุงุชEF Coreุ ููู ุงูุฏุนู ุจูุชุญุณู.
ู
ูุงุฑูุฉ Count (ุงูู LINQ Operator) ุจู Count (ุงูู Property):
- ุงูู
List<T>.Count(Property): ุฏูpropertyู ูุฌูุฏุฉ ููListูArrayูุจุนุถ ุงููcollectionsุงูุชุงููุฉ. ุจุชุฑุฌุน ุนุฏุฏ ุงูุนูุงุตุฑ ุจุณุฑุนุฉ ุฌุฏูุง ูุฅู ุงูุนุฏุฏ ุจูููู ู ุชุฎุฒู. ู ุง ูููุนุด ุชุณุชุฎุฏู ูุง ู ุนIEnumerableุนุงู ุฉู (ูุฅูIEnumerableู ุด ุจูุถู ู ุฅู ุงูุนุฏุฏ ู ุนุฑูู ู ุณุจููุง). - ุงูู
.Count()(LINQ Operator/Extension Method): ุฏูmethodุจุชุดุชุบู ู ุน ุฃูIEnumerable.- ูู ุงูู
IEnumerableุฏู ุฃุตููุงListุฃูArrayุ ุงููmethodุฏู ุจุชููู ุฐููุฉ ููุงูุฉ ุฅููุง ุชุณุชุฎุฏู ุงููCount/Lengthproperty ุนุดุงู ุชุฌูุจ ุงูุนุฏุฏ ุจุณุฑุนุฉ. - ูู ุงูู
IEnumerableุฏู ููุน ุชุงูู (ุฒู ูุชูุฌุฉqueryูุณู ู ููุฐุชุด)ุ ุงููmethodุฏู ุจุชุถุทุฑ ุชูู ุนูู ูู ุงูุนูุงุตุฑ ุนุดุงู ุชุนุฏูู (ูุฏู ู ู ูู ูููู ุฃุจุทุฃ ูู ุงููsequenceูุจูุฑุฉ). - ุงูู
Operatorูููoverloadุจูุงุฎุฏpredicateุนุดุงู ูุนุฏ ุงูุนูุงุตุฑ ุงููู ุจุชุญูู ุดุฑุท ู ุนูู (employees.Count(e => e.Gender == "Male")). ุงููPropertyุทุจุนูุง ู ุง ูููุนุด ุชุนู ู ูุฏู.
- ูู ุงูู
ุฅู
ุชู ุฃุณุชุฎุฏู
Any() ุจุฏู Count() > 0ุ
- ูู ูู ุงููู ููู
ู ุชุนุฑูู ูู โูู ููู ุฃู ุนูุตุฑ ุจูุญูู ุงูุดุฑุท ุฏูุโ ุฃู โูู ุงูููุณุชุฉ ุฏู ู
ุด ูุงุถูุฉุโุ ุฏุงูู
ูุง ุงุณุชุฎุฏู
Any(). - ุงูู
Any()ุฃุณุฑุน ุจูุชูุฑ ู ูCount() > 0ูู ู ุนุธู ุงูุญุงูุงุช (ุฎุตูุตูุง ู ุนdatabasesุฃูsequencesู ุดList/Array). - ูููุ ูุฅู
Any()ุจุชูู ุฃูู ู ุง ุชูุงูู ุฃูู ุนูุตุฑ ุจูุญูู ุงูุดุฑุท (ุฃู ุฃูู ุนูุตุฑ ูู ู ููุด ุดุฑุท). - ุงูู
Count()(ูู ู ุดList/Array) ุจุชุถุทุฑ ุชูู ุนูู ูู ุงูุนูุงุตุฑ ุนุดุงู ุชุฌูุจ ุงูุนุฏุฏ ุงููููุ ูุจุนุฏูู ุชูุงุฑูู ุจุงูุตูุฑ. - ู
ุชุณุชุฎุฏู
ุด
Count()ุบูุฑ ูู ุฃูุช ูุนููุง ู ุญุชุงุฌ ุงูุนุฏุฏ ููุณู ูุณุจุจ ู ุง. - ุงุชููู ูุง ุนู Cs Aggregate ุจุงูุชูุตูู ููุง
5. Casting / Conversion Operators (ุชุญููู ุงูููุน)
ุงูู Operators ุฏู ุจูุณุชุฎุฏู
ูุง ุนุดุงู ูุญูู ูุชูุฌุฉ LINQ query (ุงููู ุบุงูุจูุง ุจุชููู IEnumerable) ูููุน collection ู
ุนูู ูู
ุดููุฑ ุฒู List ุฃู Array ุฃู Dictionary. (ุฏูู Immediate Execution).
ToList()
- ุจุชุญูู ุงูู
sequenceููList<T>. ุฏู ุฃูุชุฑ ูุงุญุฏุฉ ุจูุณุชุฎุฏู ูุง ุบุงูุจูุง ุนุดุงู ูุฌุจุฑ ุงููqueryุฅูู ูุชููุฐ ููุงุฎุฏ ุงููุชุงุฆุฌ ููList.
IEnumerable<Employee> query = employees.Where(e => e.Salary > 5000); // Deferred
List<Employee> highEarnersList = query.ToList(); // Immediate Execution
Console.WriteLine("\nHigh Earners List (ToList):");
highEarnersList.ForEach(e => Console.WriteLine(e.Name)); // Can use List methods nowToArray()
- ุจุชุญูู ุงูู
sequenceููArray(T[]).
Employee[] highEarnersArray = employees.Where(e => e.Salary > 5000).ToArray(); // Immediate
Console.WriteLine("\nHigh Earners Array (ToArray):");
foreach(var emp in highEarnersArray) { Console.WriteLine(emp.Name); }ToDictionary()
- ุจุชุญูู ุงูู
sequenceููDictionary<TKey, TValue>. - ุจุชุญุชุงุฌ ุชุญุฏุฏ ููุง ุญุงุฌุชูู ุจู
lambda expressions:- ุงูู
keySelector: ุงุฒุงู ุชุฌูุจ ุงููKeyุจุชุงุน ุงููDictionaryู ู ูู ุนูุตุฑ ูู ุงููsequence. ุงููKeyูุงุฒู ููููunique. - ุงูู
elementSelector(ุงุฎุชูุงุฑู): ุงุฒุงู ุชุฌูุจ ุงููValueุจุชุงุน ุงููDictionary. ูู ู ุญุฏุฏุชูุดุ ุงููValueููููู ุงูุนูุตุฑ ููุณู.
- ุงูู
try
{
// Create a dictionary where Key is Employee Id, Value is Employee Name
Dictionary<int, string> employeeNameDict = employees
.ToDictionary(
emp => emp.Id, // Key selector: Use employee Id as the key
emp => emp.Name // Element selector: Use employee Name as the value
);
Console.WriteLine("\nEmployee Dictionary (Id -> Name):");
foreach (var kvp in employeeNameDict)
{
Console.WriteLine("Key: {kvp.Key}, Value: {kvp.Value}");
}
// Example where Value is the employee object itself
Dictionary<int, Employee> employeeDict = employees.ToDictionary(emp => emp.Id); // Element selector omitted
Console.WriteLine($"\nEmployee with Id 2 from Dictionary: {employeeDict[2].Name}");
// This will throw an exception if keys are not unique
// Dictionary<string, Employee> dictByGender = employees.ToDictionary(emp => emp.Gender); // Throws Exception
}
catch (Exception ex)
{
Console.WriteLine($"ToDictionary() Exception: {ex.Message}");
}
ToHashSet()
- ุจุชุญูู ุงูู
sequenceููHashSet<T>. - ุงูู
HashSetุจูุถู ู ุฅู ุงูุนูุงุตุฑ ุชูููunique(ู ููููุด ุชูุฑุงุฑ). - ู ุชุงุญ ู ู .NET 6+.
// Example: Get a set of unique genders
HashSet<string> genders = employees.Select(e => e.Gender).ToHashSet();
Console.WriteLine("\nUnique Genders (ToHashSet):");
Console.WriteLine(string.Join(", ", genders)); // Output: Male, Female (order not guaranteed)ToLookup()
- ุจุชุญูู ุงูู
sequenceููILookup<TKey, TElement>. - ุงูู
Lookupุดุจู ุงููDictionaryุ ุจุณ ุจูุณู ุญ ุจูุฌูุฏ ุฃูุชุฑ ู ู ุนูุตุฑ ูููุณ ุงููKey. ุงููValueุจูููู ุนุจุงุฑุฉ ุนูIEnumerableุจุงูุนูุงุตุฑ ุงููู ูููุง ููุณ ุงููKey. - ู
ููุฏ ุฌุฏูุง ูู ุนุงูุฒ ุชุนู
ู
groupingููุฏุงุชุง ุจุณ ูู ุดูู ุชูุฏุฑ ุชูุตู ูู ุจุงููkeyุจุณุฑุนุฉ.
// Create a Lookup grouping employees by Gender
ILookup<string, Employee> employeesByGender = employees.ToLookup(emp => emp.Gender);
Console.WriteLine("\nEmployees Lookup by Gender (ToLookup):");
// Access employees for a specific key ("Male")
Console.WriteLine("Male Employees:");
if (employeesByGender.Contains("Male")) // Good practice to check if key exists
{
foreach (var emp in employeesByGender["Male"]) // Access the IEnumerable<Employee> for the key
{
Console.WriteLine($"- {emp.Name}");
}
}
// Access employees for another key ("Female")
Console.WriteLine("Female Employees:");
foreach (var emp in employeesByGender["Female"])
{
Console.WriteLine($"- {emp.Name}");
}
// Access a non-existent key (doesn't throw exception, returns empty sequence)
Console.WriteLine("Employees with Gender 'Other':");
foreach (var emp in employeesByGender["Other"]) // This loop won't execute
{
Console.WriteLine($"- {emp.Name}");
}6. Generation Operators (ุฅูุดุงุก Sequences)
ุงูู Operators ุฏู ู
ุฎุชููุฉ ุนู ุงููู ูุงุชูุงุ ูุฅููุง ู
ุด ุจุชุดุชุบู ุนูู input sequence ู
ูุฌูุฏุฉุ ูู ููุณูุง ุจุชูุดุฆ (generate) sequence ุฌุฏูุฏุฉ. (ุฏูู Deferred Executionุ ุจุณ ุจููุดุฆูุง sequence ุชูุฏุฑ ุชุนู
ู ุนูููุง loop).
ูุงุฒู
ููุงุฏููู
ูู Static Methods ู
ู ุงูู Enumerable class.
Enumerable.Range(start, count)
- ุจุชูุดุฆ
sequenceู ู ุงูุฃุฑูุงู ุงูุตุญูุญุฉ ุงูู ุชุณูุณูุฉ. - ุงูู
start: ุงูุฑูู ุงููู ูุชุจุฏุฃ ุจูู. - ุงูู
count: ุนุฏุฏ ุงูุฃุฑูุงู ุงููู ุนุงูุฒ ุชูุดุฆูุง.
// Generate numbers from 5 to 9 (start=5, count=5)
IEnumerable<int> numberRange = Enumerable.Range(5, 5); // 5, 6, 7, 8, 9
Console.WriteLine("\nGenerated Range (Range):");
Console.WriteLine(string.Join(", ", numberRange));Enumerable.Repeat(element, count)
- ุจุชูุดุฆ
sequenceุนู ุทุฑูู ุชูุฑุงุฑ ููู ุฉ ู ุนููุฉ ุนุฏุฏ ู ุนูู ู ู ุงูู ุฑุงุช. - ุงูู
element: ุงูููู ุฉ ุงููู ุนุงูุฒ ุชูุฑุฑูุง. - ุงูู
count: ุนุฏุฏ ู ุฑุงุช ุงูุชูุฑุงุฑ.
// Repeat the string "Hi" 4 times
IEnumerable<string> repeatedHi = Enumerable.Repeat("Hi", 4); // "Hi", "Hi", "Hi", "Hi"
Console.WriteLine("\nGenerated Repetition (Repeat):");
Console.WriteLine(string.Join(", ", repeatedHi));
// Repeat the number 0 five times
var zeros = Enumerable.Repeat(0, 5); // 0, 0, 0, 0, 0
Console.WriteLine(string.Join(", ", zeros));
Enumerable.Empty<T>()
- ุจุชูุดุฆ
sequenceูุงุถูุฉ ู ู ููุน ู ุนููT. - ู
ููุฏุฉ ุฃุญูุงููุง ูู ุนุงูุฒ ุชุฑุฌุน
sequenceูุงุถูุฉ ู ูmethodุจุฏู ู ุง ุชุฑุฌุนnull.
// Create an empty sequence of Products
IEnumerable<Product> emptyProducts = Enumerable.Empty<Product>();
Console.WriteLine($"\nIs emptyProducts sequence empty? {!emptyProducts.Any()}"); // True7. Set Operators (ุนู ููุงุช ุงูู ุฌู ูุนุงุช)
ุงูู Operators ุฏู ุจุชุชุนุงู
ู ู
ุน ุงูู sequences ูุฃููุง sets (ู
ุฌู
ูุนุงุช)ุ ูุจุชุณู
ุญ ูู ุชุนู
ู ุนู
ููุงุช ุฒู ุงูุงุชุญุงุฏ ูุงูุชูุงุทุน ูุงููุฑู ุจูู ู
ุฌู
ูุนุชููุ ุฃู ุชุดูู ุงูุชูุฑุงุฑ ู
ู ู
ุฌู
ูุนุฉ ูุงุญุฏุฉ. (ุฏูู Deferred Execution).
ููุทุฉ ู ูู ุฉ: ู ูุงุฑูุฉ ุงูุนูุงุตุฑ (Overriding Equals & GetHashCode)
- ูู
ุง ุงูู
Set Operatorsุฏู ุจุชูุงุฑู ุจูู ุนูุตุฑูู ุนุดุงู ุชุนุฑู ูู ูู ุง ู ุชุณุงูููู (ุนุดุงู ู ุซููุง ุชุดูู ุงูุชูุฑุงุฑ ููDistinctุฃูUnion)ุ ูู ุจุชุณุชุฎุฏู ุทุฑููุฉ ุงูู ูุงุฑูุฉ ุงูุงูุชุฑุงุถูุฉ. - ูู ุงูุนูุงุตุฑ ุฏู
primitive types(ุฒูint,string,bool)ุ ุงูู ูุงุฑูุฉ ุจุชููู ุนูู ุงูููู ุฉ ููุณูุงุ ูุฏู ุบุงูุจูุง ุงููู ุฅุญูุง ุนุงูุฒููู. - ููู ูู ุงูุนูุงุตุฑ ุฏู
objectsู ูclassุฅุญูุง ุนุงู ูููู (ุฒูEmployeeุฃูProduct)ุ ุงูู ูุงุฑูุฉ ุงูุงูุชุฑุงุถูุฉ ุจุชููู ุจู ูุงุฑูุฉ ุงูู Reference (ุนููุงู ุงูู object ูู ุงูุฐุงูุฑุฉ)ุ ู ุด ุจู ูุงุฑูุฉ ููู ุงููpropertiesุงููู ุฌูุงู. ุฏู ู ุนูุงู ุฅู ุงุชูููEmployee objectsูููู ููุณ ุงููIdูุงููNameููุนุชุจุฑูุง ู ุฎุชูููู ูู ูู ุงinstancesู ููุตูุฉ. - ุงูุญู: ูู ุนุงูุฒ ุงูู
Set Operatorsุชูุงุฑู ุงููobjectsุจุชุงุนุชู ุจูุงุกู ุนูู ููู ุงููpropertiesุ ูุงุฒู ุชุนู ูoverrideูุงุชูููmethodsู ูู ูู ุฌูู ุงููclassุจุชุงุนู (ุงููู ูุฑุซุชูู ู ู System.Object ูููุง ุงุชููู ูุง ุนููุง ูู Cs Equality):- ุงูู
Equals(object obj): ุชุนุฑู ูููุง ุฅู ุชู ุชุนุชุจุฑ ุงุชูููobjectsู ู ุงููclassุฏู ู ุชุณุงูููู (ู ุซููุง ูู ูููู ููุณ ุงููId). - ุงูู
GetHashCode(): ูุงุฒู ูู ุงู ุชุนู ููุงoverrideุจุญูุซ ุฅู ุฃู ุงุชูููobjectsู ุชุณุงูููู ุญุณุจEqualsุ ูุงุฒู ูููู ูููู ููุณ ุงููHashCode. ูู ู ุนู ูุชุดoverrideููGetHashCodeุตุญุ ุงููSet Operators(ููู ุงูDictionaryูHashSet) ู ู ูู ุชุดุชุบู ุบูุท.- ููู ุจูุนู
ู
overrideููุงุชููู ู ุน ุจุนุถุ ูุฅู ุงููSet OperatorsูุงููCollectionsุงููู ุจุชุนุชู ุฏ ุนููhash(ุฒูHashSet,Dictionary) ุจุชุณุชุฎุฏูGetHashCodeุงูุฃูู ูุทุฑููุฉ ุณุฑูุนุฉ ุนุดุงู ุชูุณู ุงูุนูุงุตุฑ ูู ุฌู ูุนุงุช ุตุบูุฑุฉ (buckets)ุ ูุจุนุฏูู ุฌูู ุงููbucketุงููุงุญุฏ ุจุณ ุจุชูุงุฑู ุจุงุณุชุฎุฏุงูEquals. ูู ุงุชูููobjectsู ุชุณุงูููู ุจุณ ุงููHashCodeุจุชุงุนูู ู ุฎุชููุ ู ู ูู ูุชุญุทูุง ููbucketsู ุฎุชููุฉ ูู ูุชูุงุฑููุด ุจูEqualsุฃุตููุง. - ุฅุฒุงู ูุนู
ู
overrideููGetHashCodeุ ุงูุทุฑููุฉ ุงูุดุงุฆุนุฉ ุฅูู ุชุฎุชุงุฑ ุงููpropertiesุงูุฃุณุงุณูุฉ ุงููู ุจุชุนุฑู ุงููequality(ุฒู ุงููId) ูุชุฏู ุฌ ุงููHashCodesุจุชุงุนุชูู ู ุน ุจุนุถ ุจุงุณุชุฎุฏุงู ุนู ููุฉ ุฒูXOR (^)ุฃู ุจุงุณุชุฎุฏุงูHashCode.Combine()(ูู .NET ุงูุฃุญุฏุซ).
- ููู ุจูุนู
ู
- ุงูู
// Example inside Product class (assuming equality is based on Id only)
public class Product // : IEquatable<Product> // Optional: Implement IEquatable for better performance
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public double Price { get; set; }
public override string ToString() => $"Id: {Id}, Name: {Name}, Category: {Category}, Price: {Price}";
// --- Overriding Equals and GetHashCode ---
public override bool Equals(object obj)
{
// Basic implementation comparing by Id
if (obj == null || GetType() != obj.GetType())
{
return false;
}
Product other = (Product)obj;
return Id == other.Id;
// OR use pattern matching (C# 7+)
// return obj is Product other && this.Id == other.Id;
}
// Must override GetHashCode if Equals is overridden
public override int GetHashCode()
{
// Basic implementation using Id's hash code
// If using multiple properties for Equals, combine their hash codes
// return HashCode.Combine(Id, Name, Category); // Example for multiple properties (.NET Core+)
return Id.GetHashCode();
}
// --- End Overrides ---
// Optional: Implement IEquatable<T>
// public bool Equals(Product other)
// {
// if (other == null) return false;
// return this.Id == other.Id;
// }
}
- ุจุนุฏ ู
ุง ุชุนู
ู
overrideุตุญุ ุงููSet Operatorsูุชุดุชุบู ุฒู ู ุง ุฅูุช ู ุชููุน ุนูู ุงููobjectsุจุชุงุนุชู. - ุจุฏูู: ูู ู
ุด ุนุงูุฒ ุชุนู
ู
overrideูู ุงููclassููุณูุ ู ุนุธู ุงููSet Operatorsูููุงoverloadุชุงูู ุจูุงุฎุฏparameterู ู ููุนIEqualityComparer<T>. ุฏูinterfaceุจุชุนู ู ููimplementููclassู ููุตูุ ูุจุชุนุฑู ููู ุงููEqualsูุงููGetHashCodeุงููู ุฅูุช ุนุงูุฒ ุชุณุชุฎุฏู ูู ููู ูุงุฑูุฉ ุฏู ุจุณ.
Distinct()
- ุจุชุดูู ุงูุนูุงุตุฑ ุงูู
ูุฑุฑุฉ ู
ู
sequenceูุงุญุฏุฉ. ุจุชุฑุฌุนsequenceูููุง ุงูุนูุงุตุฑ ุงููuniqueุจุณ.
List<int> numbersWithDuplicates = new List<int> { 1, 2, 2, 3, 1, 4, 5, 4 };
var distinctNumbers = numbersWithDuplicates.Distinct(); // 1, 2, 3, 4, 5
Console.WriteLine("\nDistinct Numbers:");
Console.WriteLine(string.Join(", ", distinctNumbers));
// Example with Products (Needs Equals/GetHashCode override based on Id)
List<Product> productListDups = new List<Product>
{
new Product { Id = 101, Name = "Laptop", Category = "Devices", Price = 25000 },
new Product { Id = 102, Name = "Keyboard", Category = "Devices", Price = 1500 },
new Product { Id = 101, Name = "Laptop New", Category = "Devices", Price = 26000 }, // Duplicate Id
};
var distinctProducts = productListDups.Distinct(); // Will keep only one product with Id 101
Console.WriteLine("\nDistinct Products (by Id):");
foreach(var p in distinctProducts) { Console.WriteLine(p); }Union()
- ุจุชุฌูุจ ุงุชุญุงุฏ ู
ุฌู
ูุนุชูู (
sequence1 +sequence2)ุ ู ุน ุฅุฒุงูุฉ ุงูุนูุงุตุฑ ุงูู ูุฑุฑุฉ ุจูู ุงูู ุฌู ูุนุชูู ุฃู ุฌูู ูู ู ุฌู ูุนุฉ.
List<int> listA = new List<int> { 1, 2, 3, 4 };
List<int> listB = new List<int> { 3, 4, 5, 6 };
var unionResult = listA.Union(listB); // 1, 2, 3, 4, 5, 6
Console.WriteLine("\nUnion of listA and listB:");
Console.WriteLine(string.Join(", ", unionResult));Concat()
- ุจุชุฏู ุฌ (Concatenate) ู ุฌู ูุนุชูู ูุฑุง ุจุนุถ ู ู ุบูุฑ ู ุง ุชุดูู ุฃู ุชูุฑุงุฑ. ุจุชุฑุฌุน ูู ุนูุงุตุฑ ุงูุฃููู ูุจุนุฏูุง ูู ุนูุงุตุฑ ุงูุชุงููุฉ.
- ุฏู ุฒู
UNION ALLููSQL.
var concatResult = listA.Concat(listB); // 1, 2, 3, 4, 3, 4, 5, 6
Console.WriteLine("\nConcatenation of listA and listB:");
Console.WriteLine(string.Join(", ", concatResult));
// Note: listA.Union(listB) is equivalent to listA.Concat(listB).Distinct()Intersect()
- ุจุชุฌูุจ ุชูุงุทุน ู ุฌู ูุนุชููุ ูุนูู ุงูุนูุงุตุฑ ุงูู ุดุชุฑูุฉ ุงูู ูุฌูุฏุฉ ูู ุงูู ุฌู ูุนุชูู ุงูุงุชููู.
var intersectResult = listA.Intersect(listB); // 3, 4
Console.WriteLine("\nIntersection of listA and listB:");
Console.WriteLine(string.Join(", ", intersectResult));Except()
- ุจุชุฌูุจ ุงููุฑู ุจูู ู ุฌู ูุนุชูู. ุจุชุฑุฌุน ุงูุนูุงุตุฑ ุงูู ูุฌูุฏุฉ ูู ุงูู ุฌู ูุนุฉ ุงูุฃููู ูู ุด ู ูุฌูุฏุฉ ูู ุงูู ุฌู ูุนุฉ ุงูุชุงููุฉ.
var exceptResult = listA.Except(listB); // 1, 2 (Elements in A that are not in B)
Console.WriteLine("\nElements in listA Except those in listB:");
Console.WriteLine(string.Join(", ", exceptResult));
var exceptResultReverse = listB.Except(listA); // 5, 6 (Elements in B that are not in A)
Console.WriteLine("\nElements in listB Except those in listA:");
Console.WriteLine(string.Join(", ", exceptResultReverse));ุงูู ...By Operators (.NET 6+)
ุฒู ู
ุง ููู MaxBy/MinByุ ููู ูู
ุงู overloads ุฌุฏูุฏุฉ ููู Set Operators ุฏู ู
ู ุฃูู .NET 6 ุจุชูุชูู ุจู By (ุฒู DistinctBy, UnionBy, IntersectBy, ExceptBy).
- ูุงูุฏุชูู
: ุจูุฎูููู ุชุญุฏุฏ
key selector(ูุนููlambda expressionุจุชุฎุชุงุฑpropertyู ุนููุฉ) ุนุดุงู ุงูู ูุงุฑูุฉ ุชุชู ุจูุงุกู ุนูู ุงููkeyุฏู ุจุณุ ุจุฏู ู ุง ุชุญุชุงุฌ ุชุนู ูoverrideููEquals/GetHashCodeุฃู ุชุณุชุฎุฏูIEqualityComparer.
ู
ุซุงู: ูุฌูุจ ุงูู
ูุชุฌุงุช ุงูู unique ุจูุงุกู ุนูู ุงูู Category ุจุณ:
// Using DistinctBy ( .NET 6+) to get one product per category
var distinctByCategory = products.DistinctBy(p => p.Category);
Console.WriteLine("\nDistinct Products by Category (DistinctBy):");
foreach (var p in distinctByCategory)
{
Console.WriteLine(p); // Gets Laptop (Devices), T-Shirt (Clothing) - or others depending on which comes first
}
// Example: Union products based on Category key
List<Product> moreProducts = new List<Product> {
new Product { Id = 201, Name = "Jeans", Category = "Clothing", Price = 1200 },
new Product { Id = 202, Name = "Monitor", Category = "Devices", Price = 5000 }
};
var unionByCategory = products.UnionBy(moreProducts, p => p.Category);
Console.WriteLine("\nUnion By Category:");
foreach (var p in unionByCategory) { Console.WriteLine(p); } // Shows one product per unique category from both listsุงูู ...By operators ุฏู ุจุชุจุณุท ุงูุฏููุง ุฌุฏูุง ูู
ุง ุชููู ุนุงูุฒ ุชุนู
ู ู
ูุงุฑูุฉ ุจูุงุกู ุนูู property ูุงุญุฏุฉ ุฃู ุฃูุชุฑ ู
ู ุบูุฑ ู
ุง ุชุนุฏู ุงูู class ุงูุฃุตูู.
8. Quantifier Operators (ุชุญุฏูุฏ ุงููู ูุฉ - Boolean)
ุงูู Operators ุฏู ุจุชุดุชุบู ุนูู ุงูู sequence ูููุง ุนุดุงู ุชุฑุฌุน ููู
ุฉ boolean (true ุฃู false) ุจุชุฌุงูุจ ุนูู ุณุคุงู ุนู ูู
ูุฉ ุงูุนูุงุตุฑ ุงููู ุจุชุญูู ุดุฑุท ู
ุนูู. (ุฏูู ูููู
ุณููู Immediate Execution ูู ุงูุบุงูุจ ูุฅููู
ูุงุฒู
ููุตููุง ููุชูุฌุฉ true/false).
Any()
- ุจุชุฑุฌุน
trueูู ููู ุนูุตุฑ ูุงุญุฏ ุนูู ุงูุฃูู ูู ุงููsequenceุจูุญูู ุงูุดุฑุท ุงููู ู ุฏูููููุง. - ูู ู
ู ุบูุฑ ุดุฑุท (
Any())ุ ุจุชุฑุฌุนtrueูู ุงููsequenceู ุด ูุงุถูุฉ (ูููุง ุนูุตุฑ ูุงุญุฏ ุนูู ุงูุฃูู). - ุจุชูู ุฃูู ู ุง ุชูุงูู ุฃูู ุนูุตุฑ ูุญูู ุงูุดุฑุท (ุนุดุงู ูุฏู ุณุฑูุนุฉ).
bool anyMales = employees.Any(e => e.Gender == "Male"); // true
Console.WriteLine($"\nAny males? {anyMales}");
bool anySalaryOver9k = employees.Any(e => e.Salary > 9000); // false
Console.WriteLine($"Any salary > 9k? {anySalaryOver9k}");
bool isEmployeeListNotEmpty = employees.Any(); // true
Console.WriteLine($"Is employees list not empty? {isEmployeeListNotEmpty}");
List<int> emptyList = new List<int>();
bool isEmptyListNotEmpty = emptyList.Any(); // false
Console.WriteLine($"Is emptyList not empty? {isEmptyListNotEmpty}");All()
- ุจุชุฑุฌุน
trueูู ูู ุงูุนูุงุตุฑ ูู ุงููsequenceุจูุญูููุง ุงูุดุฑุท ุงููู ู ุฏูููููุง. - ูู ุงูู
sequenceูุงุถูุฉุ ุจุชุฑุฌุนtrue(ูุฅูู ู ููุด ููุง ุนูุตุฑ ู ูุฏุฑุด ูุญูู ุงูุดุฑุท!). - ุฏู ุฒู ุงูู TrueForAll in List
bool allEarnMoreThan4k = employees.All(e => e.Salary > 4000); // true (assuming sample data)
Console.WriteLine($"\nAll earn > 4k? {allEarnMoreThan4k}");
bool allAreMale = employees.All(e => e.Gender == "Male"); // false
Console.WriteLine($"All are male? {allAreMale}");
bool allSatisfyInEmpty = emptyList.All(x => x > 5); // true
Console.WriteLine($"All satisfy condition in empty list? {allSatisfyInEmpty}");Contains()
- ุจุชุฑุฌุน
trueูู ุงููsequenceุจุชุญุชูู ุนูู ุนูุตุฑ ู ุนูู ุฃูุช ุจุชุฏูุฑ ุนููู. - ุจุชุญุชุงุฌ ุชุนู
ู
overrideููEquals/GetHashCodeูู ุจุชุฏูุฑ ุนููobjectู ุฑูุจ. - ููู
overloadุจูุงุฎุฏIEqualityComparer.
List<string> letters = new List<string> { "A", "B", "C" };
bool hasB = letters.Contains("B"); // true
Console.WriteLine($"\nLetters list contains 'B'? {hasB}");
bool hasX = letters.Contains("X"); // false
Console.WriteLine($"Letters list contains 'X'? {hasX}");
// Example with objects (needs Equals/GetHashCode override)
Product laptop = new Product { Id = 101, Name = "Laptop", Category = "Devices", Price = 25000 };
bool productListHasLaptop = products.Contains(laptop); // true (because we overrode Equals based on Id)
Console.WriteLine($"Products list contains laptop (Id 101)? {productListHasLaptop}");SequenceEqual()
- ุจุชูุงุฑู ุจูู ุงุชููู
sequencesุนุดุงู ุชุดูู ูู ูู ุง ู ุชุณุงููุชูู. - ุจุชููู ู
ุชุณุงููุฉ ูู:
- ูููู ููุณ ุนุฏุฏ ุงูุนูุงุตุฑ.
- ูู ุนูุตุฑ ูู ุงูู
sequenceุงูุฃููู ุจูุณุงูู ุงูุนูุตุฑ ุงูู ูุงุจู ูู ูู ููุณ ุงููindexูู ุงููsequenceุงูุชุงููุฉ (ุจุงุณุชุฎุฏุงูEqualsุงูุงูุชุฑุงุถู ุฃูoverrideุฃูIEqualityComparer).
List<int> seq1 = new List<int> { 1, 2, 3 };
List<int> seq2 = new List<int> { 1, 2, 3 };
List<int> seq3 = new List<int> { 1, 3, 2 }; // Different order
List<int> seq4 = new List<int> { 1, 2 }; // Different count
bool seq1EqualsSeq2 = seq1.SequenceEqual(seq2); // true
Console.WriteLine($"\nSequenceEqual(seq1, seq2)? {seq1EqualsSeq2}");
bool seq1EqualsSeq3 = seq1.SequenceEqual(seq3); // false (order matters)
Console.WriteLine($"SequenceEqual(seq1, seq3)? {seq1EqualsSeq3}");
bool seq1EqualsSeq4 = seq1.SequenceEqual(seq4); // false (count matters)
Console.WriteLine($"SequenceEqual(seq1, seq4)? {seq1EqualsSeq4}");
9. Zipping Operator (ุงูุฏู ุฌ ุจุงูุชุฑุชูุจ)
ุนูุฏูุง operator ูุงุญุฏ ููุง ูู Zip(). (ุฏู Deferred Execution).
Zip()
- ุจูุฏู
ุฌ ุนูุตุฑ ุนูุตุฑ ู
ู ุงุชููู
sequencesู ุน ุจุนุถ ุจูุงุกู ุนูู ุงูุชุฑุชูุจ (index). - ุจูุงุฎุฏ
lambda expressionุจุชุญุฏุฏ ุฅุฒุงู ุชุฏู ุฌ ุงูุนูุตุฑ ู ู ุงููsequenceุงูุฃููู ู ุน ุงูุนูุตุฑ ุงูู ูุงุจู ูู ูู ุงููsequenceุงูุชุงููุฉ ุนุดุงู ุชูุชุฌ ุนูุตุฑ ุฌุฏูุฏ ูู ุงููresult sequence. - ุงูุนู
ููุฉ ุจุชูู ุฃูู ู
ุง ุฃูุตุฑ
sequenceู ู ุงูุงุชููู ุชุฎูุต. ุญุฌู ุงููresult sequenceุจูููู ุจุญุฌู ุฃูุตุฑsequence.
List<string> studentNames = new List<string> { "Amr", "Fatma", "Hassan", "Nour" };
List<int> studentScores = new List<int> { 85, 92, 78 }; // Shorter list
// Zip names and scores together
var studentInfo = studentNames.Zip(studentScores,
(name, score) => $"{name} scored {score}");
// result sequence will have 3 elements only
Console.WriteLine("\nZipped Student Info (Zip):");
foreach (var info in studentInfo)
{
Console.WriteLine(info);
}
// Output:
// Amr scored 85
// Fatma scored 92
// Hassan scored 78
// (Nour is ignored because studentScores ended)10. Grouping Operators (ุงูุชุฌู ูุน)
ุงูู Operator ุงูุฃุณุงุณู ููุง ูู GroupBy(). ุจูุณุชุฎุฏู
ู ุนุดุงู ูุฌู
ุน ุนูุงุตุฑ ุงูู sequence ูู ู
ุฌู
ูุนุงุช ุจูุงุกู ุนูู key ู
ุนูู. (ุฏู Deferred Execution).
GroupBy()
- ุจูุงุฎุฏ
lambda expressionุจุชุญุฏุฏ ุงููkeyุงููู ููุชู ุงูุชุฌู ูุน ุนูู ุฃุณุงุณู (ู ุซููุง ูุฌู ุน ุงูู ูุธููู ุญุณุจ ุงููDepartment). - ุจูุฑุฌุน
sequenceุฌุฏูุฏุฉุ ูู ุนูุตุฑ ูููุง ุนุจุงุฑุฉ ุนูgroup. - ูู
groupุจูููู ูููุง ุญุงุฌุชูู ุฃุณุงุณูุชูู:- ุงูู
Key: ุงูููู ุฉ ุงููู ุชู ุงูุชุฌู ูุน ุจููุง (ู ุซููุง ุงุณู ุงููุณู โHRโ). - ุงูู
IEnumerable<T>: ู ุฌู ูุนุฉ ุงูุนูุงุตุฑ ุงูุฃุตููุฉ ุงููู ุจุชูุชู ู ูููgroupุฏู (ู ุซููุง ูู ุงูู ูุธููู ุงููู ูู ูุณู โHRโ). ุงููgroupููุณูุง ุจุชููู ู ู ููุนIGrouping<TKey, TElement>.
- ุงูู
- ููู ูุงุณ ุจุชูุถู ุชูุชุจ
GroupByุจุงูู Query Syntax ูุฅููุง ู ู ูู ุชููู ุฃูุถุญ ุดููุฉ ู ุน ููู ุฉgroup by.
ู ุซุงู: ุชุฌู ูุน ุงูู ูุชุฌุงุช ุญุณุจ ุงูู Category:
Console.WriteLine("\n--- Grouping Operators ---");
// Group products by Category using Query Syntax (often clearer for grouping)
var productsByCategoryQuery = from p in products
group p by p.Category; // Group product 'p' by its 'Category' property
Console.WriteLine("Products Grouped by Category (Query Syntax):");
// productsByCategoryQuery is IEnumerable<IGrouping<string, Product>>
foreach (var categoryGroup in productsByCategoryQuery)
{
Console.WriteLine($"Category: {categoryGroup.Key}"); // The Key is the Category name
// categoryGroup itself is an IEnumerable<Product> for this category
foreach (var product in categoryGroup)
{
Console.WriteLine($"- {product.Name} ({product.Price})");
}
}
// Group products by Category using Fluent Syntax
var productsByCategoryFluent = products.GroupBy(p => p.Category);
Console.WriteLine("\nProducts Grouped by Category (Fluent Syntax):");
foreach (var categoryGroup in productsByCategoryFluent)
{
Console.WriteLine($"Category: {categoryGroup.Key}");
foreach (var product in categoryGroup)
{
Console.WriteLine($"- {product.Name} ({product.Price})");
}
}ุงุณุชุฎุฏุงู
into ู
ุน group by ูู ุงูู Query Syntax:
ุฒู ู
ุง ุงุณุชุฎุฏู
ูุง into ู
ุน join ุนุดุงู ูุนู
ู Left Joinุ ู
ู
ูู ูุณุชุฎุฏู
ูุง ู
ุน group by ุนุดุงู ููู
ู ุงูู query ุนูู ุงูู groups ุงููู ุงุชูููุช. ุจูุณุชุฎุฏู
into ุนุดุงู ูุฏู ุงุณู
ููู group variable ูููุฏุฑ ูุนู
ู ุนููู where ุฃู orderby ุฃู select ุจุนุฏ ูุฏู.
ู
ุซุงู: ูุงุช ุงูู Categories ุงููู ูููุง ุฃูุชุฑ ู
ู ู
ูุชุฌ ูุงุญุฏ (Count > 1)ุ ูุฑุชุจูู
ุฃุจุฌุฏููุงุ ูุงุนุฑุถ ุงุณู
ุงูู Category ูุนุฏุฏ ุงูู
ูุชุฌุงุช ูููุง.
// Using Query Syntax with 'into' after 'group by'
var categoriesWithMoreThanOneProduct =
from p in products // Start with products
group p by p.Category // Group them by category
into categoryGroup // Put the resulting group into 'categoryGroup' variable
where categoryGroup.Count() > 1 // Filter the groups (keep only those with count > 1)
orderby categoryGroup.Key // Order the remaining groups by category name (the key)
select new // Select the desired output
{
CategoryName = categoryGroup.Key,
ProductCount = categoryGroup.Count()
};
Console.WriteLine("\nCategories with more than 1 product (Query Syntax with into):");
foreach (var catInfo in categoriesWithMoreThanOneProduct)
{
Console.WriteLine($"{catInfo.CategoryName}: {catInfo.ProductCount} products");
}
// Equivalent using Fluent Syntax (chaining methods)
var categoriesWithMoreThanOneProductFluent = products
.GroupBy(p => p.Category) // Group
.Where(categoryGroup => categoryGroup.Count() > 1) // Filter groups
.OrderBy(categoryGroup => categoryGroup.Key) // Order groups
.Select(categoryGroup => new // Select output
{
CategoryName = categoryGroup.Key,
ProductCount = categoryGroup.Count()
});
Console.WriteLine("\nCategories with more than 1 product (Fluent Syntax):");
foreach (var catInfo in categoriesWithMoreThanOneProductFluent)
{
Console.WriteLine($"{catInfo.CategoryName}: {catInfo.ProductCount} products");
}11. Partitioning Operators (ุชูุณูู ุงูู Sequence)
ุงูู Operators ุฏู ุจูุณุชุฎุฏู
ูุง ุนุดุงู ูุงุฎุฏ ุฌุฒุก (partition) ู
ุนูู ู
ู ุงูู sequenceุ ูุบุงูุจูุง ุจูุณุชุฎุฏู
ูุง ูู Pagination (ุนุฑุถ ุงูุฏุงุชุง ุตูุญุฉ ุตูุญุฉ). (ุฏูู Deferred Execution).
Take(count)
- ุจูุงุฎุฏ ุฃูู
countุนูุตุฑ ู ู ุจุฏุงูุฉ ุงููsequence.
List<int> nums = Enumerable.Range(1, 10).ToList(); // 1 to 10
var firstThree = nums.Take(3); // 1, 2, 3
Console.WriteLine($"\nTake(3): {string.Join(", ", firstThree)}");TakeLast(count) (.NET Standard 2.1+)
- ุจูุงุฎุฏ ุขุฎุฑ
countุนูุตุฑ ู ู ููุงูุฉ ุงููsequence.
var lastTwo = nums.TakeLast(2); // 9, 10
Console.WriteLine($"TakeLast(2): {string.Join(", ", lastTwo)}");Skip(count)
- ุจูุชุฎุทู (skip) ุฃูู
countุนูุตุฑุ ูุจูุฑุฌุน ุจุงูู ุงููsequence.
var skipFirstThree = nums.Skip(3); // 4, 5, 6, 7, 8, 9, 10
Console.WriteLine($"Skip(3): {string.Join(", ", skipFirstThree)}");SkipLast(count) (.NET Standard 2.1+)
- ุจูุชุฎุทู ุขุฎุฑ
countุนูุตุฑุ ูุจูุฑุฌุน ุงูุฌุฒุก ุงูุฃููุงูู ู ู ุงููsequence.
var skipLastTwo = nums.SkipLast(2); // 1, 2, 3, 4, 5, 6, 7, 8
Console.WriteLine($"SkipLast(2): {string.Join(", ", skipLastTwo)}");TakeWhile(predicate)
- ุจูุงุฎุฏ ุนูุงุตุฑ ู
ู ุจุฏุงูุฉ ุงูู
sequenceุทูู ู ุง ุงูุดุฑุท (predicate) ู ุชุญูู. - ุจุชูู ุชู ุงู ูุง ุฃูู ู ุง ุชูุงูู ุฃูู ุนูุตุฑ ู ุด ุจูุญูู ุงูุดุฑุท. ุญุชู ูู ุงูุนูุงุตุฑ ุงููู ุจุนุฏู ุจุชุญูู ุงูุดุฑุท ุชุงููุ ู ุด ุจุชุงุฎุฏูู .
- ููู
overloadุจูุงุฎุฏ ุงููindexูู ุงู (TakeWhile((element, index) => ...)).
int[] numbersMixed = { 1, 2, 3, 6, 7, 2, 8, 9 };
var takeWhileLessThan5 = numbersMixed.TakeWhile(n => n < 5); // 1, 2, 3 (stops at 6)
Console.WriteLine($"\nTakeWhile(n < 5): {string.Join(", ", takeWhileLessThan5)}");
var takeWhileIndexLessThan3 = numbersMixed.TakeWhile((n, index) => index < 3); // 1, 2, 3
Console.WriteLine($"TakeWhile(index < 3): {string.Join(", ", takeWhileIndexLessThan3)}");SkipWhile(predicate)
- ุจูุชุฎุทู ุนูุงุตุฑ ู
ู ุจุฏุงูุฉ ุงูู
sequenceุทูู ู ุง ุงูุดุฑุท (predicate) ู ุชุญูู. - ุจุชุจุฏุฃ ุชุงุฎุฏ ุงูุนูุงุตุฑ ุฃูู ู ุง ุชูุงูู ุฃูู ุนูุตุฑ ู ุด ุจูุญูู ุงูุดุฑุทุ ูุจุชุงุฎุฏ ุงูุนูุตุฑ ุฏู ููู ุงููู ุจุนุฏู (ู ู ุบูุฑ ู ุง ุชุนู ู check ููุดุฑุท ุชุงูู).
- ููู
overloadุจูุงุฎุฏ ุงููindexูู ุงู.
var skipWhileLessThan5 = numbersMixed.SkipWhile(n => n < 5); // 6, 7, 2, 8, 9 (skips 1, 2, 3, starts taking from 6)
Console.WriteLine($"\nSkipWhile(n < 5): {string.Join(", ", skipWhileLessThan5)}");
var skipWhileIndexLessThan3 = numbersMixed.SkipWhile((n, index) => index < 3); // 6, 7, 2, 8, 9
Console.WriteLine($"SkipWhile(index < 3): {string.Join(", ", skipWhileIndexLessThan3)}");Chunk(size) (.NET 6+)
- ุจุชูุณู
ุงูู
sequenceูู โูุทุนโ (chunks)ุ ูู ูุทุนุฉ ุนุจุงุฑุฉ ุนูarrayุจุงูุญุฌู (size) ุงููู ุญุฏุฏุชู (ู ุง ุนุฏุง ุขุฎุฑ ูุทุนุฉ ู ู ูู ุชููู ุฃุตุบุฑ). - ุจุชุฑุฌุน
IEnumerable<T[]>(sequence of arrays).
var chunksOfThree = nums.Chunk(3); // [1,2,3], [4,5,6], [7,8,9], [10]
Console.WriteLine("\nChunk(3):");
foreach (var chunk in chunksOfThree)
{
Console.WriteLine($"- [{string.Join(", ", chunk)}]");
}ููุฑุฉ ุงูู Pagination
ุบุงูุจูุง ุจูุณุชุฎุฏู
Skip() ู Take() ู
ุน ุจุนุถ ุนุดุงู ูุนู
ู Pagination. ุจูููู ุนูุฏู:
- ุงูู
pageNumber: ุฑูู ุงูุตูุญุฉ ุงููู ุงูู ุณุชุฎุฏู ุนุงูุฒูุง (ุจูุจุฏุฃ ู ู 1). - ุงูู
pageSize: ุนุฏุฏ ุงูุนูุงุตุฑ ุงููู ุนุงูุฒ ุชุนุฑุถูุง ูู ูู ุตูุญุฉ (ู ุซููุง 10).
ุงูู ุนุงุฏูุฉ ุจุชููู:
int pageNumber = 2; // Example: User wants page 2
int pageSize = 3; // Example: Show 3 items per page
var paginatedResults = nums
.Skip((pageNumber - 1) * pageSize) // Skip items of previous pages
.Take(pageSize); // Take items for the current page
// For page 2, pageSize 3: Skip((2-1)*3) = Skip(3). Take(3). Result: 4, 5, 6
Console.WriteLine($"\nPagination (Page {pageNumber}, Size {pageSize}): {string.Join(", ", paginatedResults)}");ููู ู
ุด ุจูุณุชุฎุฏู
Chunk() ููู Paginationุ
- ุงูู
Chunk()ุจุชูุณู ุงูุฏุงุชุง ูููุง ุงูุฃูู ูู ุฌู ูุนุฉ ู ู ุงููchunksูู ุงููmemory. ุฏู ู ู ูู ูููู ู ุด ูููุณ ูู ุงูุฏุงุชุง ุฌุงูุฉ ู ูdatabaseุฃู ุญุฌู ูุง ูุจูุฑ ุฌุฏูุง. ุฅูุช ู ุด ุนุงูุฒ ุชุญู ู ูู ุงูุฏุงุชุง ุนุดุงู ุชุงุฎุฏ ุตูุญุฉ ูุงุญุฏุฉ ุจุณ. - ุงูู
Skip().Take()ุจุชุดุชุบูDeferred Executionุจุดูู ุฃูุถู. ูู ุจุชุณุชุฎุฏู ูุง ู ุนdatabase(ุจุงุณุชุฎุฏุงูIQueryable)ุ ุงููEF Coreููุชุฑุฌู ูุง ููSQL queryุจูุฌูุจ ุจุณ ุงูุฏุงุชุง ุจุชุงุนุฉ ุงูุตูุญุฉ ุงูู ุทููุจุฉ ู ู ุงููdatabase(ุฒู ุงุณุชุฎุฏุงูOFFSET FETCHูู SQL Server)ุ ูุฏู ุฃููุฃ ุจูุชูุฑ.
12. Joins Operators (ุฑุจุท ุงูู Sequences)
ุงูู Operators ุฏู ุจูุณุชุฎุฏู
ูุง ุนุดุงู ูุฑุจุท ุจูู ุงุชููู sequences ุฃู ุฃูุชุฑ ุจูุงุกู ุนูู key ู
ุดุชุฑู ุจูููู
ุ ุฒู ู
ุง ุจูุนู
ู JOIN ูู SQL.
ู ูุญูุธุฉ ู ูู ุฉ: Joins ู ุน Local Sequences vs Databases
- ููุง ู
ู
ูู ูุดุฑุญ ุงูู
Joinsุฏู ุนููlocal sequences(ุฒูList<Employee>ูList<Department>ูู ุงูุฐุงูุฑุฉ)ุ ุจุณ ูุงูุฏุชูุง ุงูุญููููุฉ ูููุชูุง ุจุชุธูุฑ ุฃูุชุฑ ูู ุง ุจูุณุชุฎุฏู ูุง ู ุนdatabase tablesู ู ุฎูุงูEF Core. - ูุฅู ุงูู
EF CoreุจูุชุฑุฌูLINQ JoinsููSQL Joinsุจุชุชููุฐ ุนูู ุงููdatabase serverููุณูุ ูุฏู ุจูููู ูุนุงู ุฌุฏูุง.
ุฅู ุชู ุจูุณุชุฎุฏู ุงูู Joinุ
ุจูุณุชุฎุฏู
ูุง ูู
ุง ูููู ู
ุญุชุงุฌูู ูุฌูุจ ุฏุงุชุง ู
ุฑุชุจุทุฉ ุจุจุนุถูุง ู
ู ุฃูุชุฑ ู
ู table ูู ููุณ ุงูู query. ู
ุซููุงุ ูุฌูุจ ุงุณู
ุงูู
ูุธู ูุงุณู
ุงููุณู
ุงููู ุดุบุงู ููู.
ุงูู Join Operators ุงูุฃุณุงุณูุฉ
ุนูุฏูุง 2 operators ุฃุณุงุณููู ููู Join ูู LINQ:
- ุงูู
Join(): ุจูุณุชุฎุฏู ูุง ุนุดุงู ูุนู ูInner Join. ุณููุฉ ูู ุจุงุดุฑุฉ ูุณุจููุง. - ุงูู
GroupJoin(): ุจูุณุชุฎุฏู ูุง ูุฃุณุงุณ ูุนู ูLeft Outer Join(ููู ุงู ูููุง ุงุณุชุฎุฏุงู ุชุงูู ู ุนlocal sequencesู ุด ู ูู ุฃูู ู ุนdatabases).
(ูููุชุฑุถ ุฅููุง ุนูุฏูุง DbContext ุงุณู
ู context ููู DbSet<Employee> ุงุณู
ู Employees ู DbSet<Department> ุงุณู
ู Departments ู
ุฑุจูุทูู ุจู database).
Join() Operator (ููู Inner Join)
ุงูู Inner Join ุจูุฌูุจ ุจุณ ุงูุนูุงุตุฑ ุงูู
ุดุชุฑูุฉ ุจูู ุงูู
ุฌู
ูุนุชููุ ูุนูู:
- ุงูู
ูุธููู ุงููู ูููู
DepartmentIdู ุดnullูู ูุฌูุฏ ูุนููุง ููIdููDepartments table. - ุงูุฃูุณุงู ุงููู ูููุง ู ูุธููู ูุนููุง.
ูุชุงุจุฉ ุงูู Inner Join ุจู Query Syntax (ุงูุทุฑููุฉ ุงูู
ูุถูุฉ ููู Joins)
ุงูู Query Syntax ุบุงูุจูุง ุจุชููู ุฃุณูู ูู ุงููุฑุงุกุฉ ูุงููุชุงุจุฉ ูุนู
ููุงุช ุงูู Join.
Console.WriteLine("\n--- Inner Join (Query Syntax) ---");
// Get Employee Name and Department Name for employees who have a department
var innerJoinResultQuery =
from emp in context.Employees // Start with Employees (can start with either)
join dept in context.Departments // Join with Departments
on emp.DepartmentId equals dept.Id // The JOIN CONDITION: FK == PK
select new // Select the desired output
{
EmployeeName = emp.Name,
DepartmentName = dept.Name
};
// Execute and display
// Assuming context is an instance of your DbContext
// foreach (var item in innerJoinResultQuery)
// {
// Console.WriteLine($"Employee: {item.EmployeeName}, Department: {item.DepartmentName}");
// }
Console.WriteLine("(Query would fetch matching employees and departments)");
ุดุฑุญ:
- ุงูู
from emp in context.Employees: ุจูุจุฏุฃ ุจุงููtableุงูุฃูู. - ุงูู
join dept in context.Departments: ุจููููู ุงุนู ูjoinู ุน ุงููtableุงูุชุงูู. - ุงูู
on emp.DepartmentId equals dept.Id: ุฏู ุดุฑุท ุงูุฑุจุท. ู ูู : ุงูุทุฑู ุงูุดู ุงู (emp.DepartmentId) ูุงุฒู ูููู ุงููkeyู ู ุงููsequenceุงููู ุฌุงูุฉ ูู ุฌู ูุฉfromุงูุฃููู (emp)ุ ูุงูุทุฑู ุงููู ูู (dept.Id) ูุงุฒู ูููู ุงููkeyู ู ุงููsequenceุงููู ุฌุงูุฉ ูู ุฌู ูุฉjoin(dept). ูู ุนูุณุชูู ู ู ูู ูุดุชุบู ุจุณ ุงูุฃูุถุญ ุชู ุดู ุจุงูุชุฑุชูุจ. - ุงูู
select new { ... }: ุจูุฎุชุงุฑ ุงูุญููู ุงููู ุนุงูุฒูููุง ู ู ุงููempูุงููdept.
ูุชุงุจุฉ ุงูู Inner Join ุจู Fluent Syntax
ู
ู
ูู ูุนู
ู ููุณ ุงูู Inner Join ุจุงูู Fluent Syntaxุ ุจุณ ุงูู syntax ุจุชุงุนูุง ุจูููู ุฃุทูู ุดููุฉ:
Console.WriteLine("\n--- Inner Join (Fluent Syntax) ---");
var innerJoinResultFluent = context.Employees // Start with the 'outer' sequence
.Join(
context.Departments, // The 'inner' sequence to join with
emp => emp.DepartmentId, // Outer Key Selector (Key from the first sequence - emp)
dept => dept.Id, // Inner Key Selector (Key from the second sequence - dept)
(emp, dept) => new // Result Selector (Combines matching emp and dept)
{
EmployeeName = emp.Name,
DepartmentName = dept.Name
}
);
// Execute and display (same result as Query Syntax)
// foreach (var item in innerJoinResultFluent)
// {
// Console.WriteLine($"Employee: {item.EmployeeName}, Department: {item.DepartmentName}");
// }
Console.WriteLine("(Query would fetch matching employees and departments)");ุดุฑุญ:
- ุงูู
context.Employees.Join(...): ุจูุจุฏุฃ ุจุงููsequenceุงูุฃููู ูููุงุฏูJoin. - ุงูู
context.Departments: ุงููparameterุงูุฃูู ูู ุงููsequenceุงูุชุงููุฉ ุงููู ููุนู ูjoinู ุนุงูุง. - ุงูู
emp => emp.DepartmentId: ุงููparameterุงูุชุงูู ููlambdaุจุชุฎุชุงุฑ ุงููkeyู ู ุงููsequenceุงูุฃููู (outer sequence). - ุงูู
dept => dept.Id: ุงููparameterุงูุชุงูุช ููlambdaุจุชุฎุชุงุฑ ุงููkeyู ู ุงููsequenceุงูุชุงููุฉ (inner sequence). - ุงูู
(emp, dept) => new { ... }: ุงููparameterุงูุฑุงุจุน ููlambdaุจุชุญุฏุฏ ุดูู ุงููุชูุฌุฉ. ุจุชุงุฎุฏ ุนูุตุฑ ู ู ุงูุฃููู (emp) ูุนูุตุฑ ู ู ุงูุชุงููุฉ (dept) ููinputูุจุชุฑุฌุน ุงููoutputุงููู ุฅูุช ุนุงูุฒู.
ูู ููู ูุฑู ุจูู ุงูุทุฑููุชููุ ูุฃุ ุงูุงุชููู ุจูุชุฑุฌู
ูุง ูููุณ ุงูู INNER JOIN ูู SQL ูุจูุฏูุง ููุณ ุงููุชูุฌุฉ. ุงุณุชุฎุฏู
ุงููู ุชุฑูุญูุ ุจุณ ุงูู Query Syntax ุบุงูุจูุง ุฃุณูู ููู Join.
ู
ูุญูุธุฉ ุนู Overload ุงูู IEqualityComparer
- ููู
overloadุชุงูู ูููmethodุจุชุงุนุชJoinุจูุงุฎุฏparameterุฒูุงุฏุฉ ู ู ููุนIEqualityComparer. - ุงุชููู
ูุง ุนู ุงูู
interfaceุฏู ุฒู ุงู ู ุน ุงููSet Operators(ุฒูDistinct,Unionโฆ). ูุงูุฏุชู ุฅูู ุจูุฎููู ุชุชุญูู ุฅุฒุงู ุจูุชู ู ูุงุฑูุฉ ุงููobjects. - ุงู
ุชู ู
ู
ูู ูุญุชุงุฌู ูุธุฑููุงุ
- ูู
ุง ุจูุนู
ู
joinุจููlocal sequences(ู ุดdatabase tables) ูุงููkeysุงููู ุจููุงุฑููุง ุนุจุงุฑุฉ ุนูcomplex objects(ุฒูclassุงุณู ูAddress) ูู ุดprimitive types(ุฒูintุฃูstring). ูู ุงูุญุงูุฉ ุฏูุ ุงูู ูุงุฑูุฉ ุงูุนุงุฏูุฉ ูุชูุงุฑูreferencesุ ููู ุฅุญูุง ู ู ูู ูููู ุนุงูุฒูู ููุงุฑู ุงููvaluesุงููู ุฌูุง ุงููobjects. ุงููIEqualityComparerุจูุณู ุญ ุจุฏู. - ุฃู ูู ุญุงูุฉ ุงูู
composite primary keysุงูู ุนูุฏุฉ ุฌุฏูุง (ุณููุงุฑูู ูุงุฏุฑ).
- ูู
ุง ุจูุนู
ู
- ูู ุจูุญุชุงุฌู ู
ุน ุงูู Databaseุ
- ูุฃุ ุบุงูุจูุง ู
ุด ุจูุญุชุงุฌู ุฎุงูุต. ูููุ ูุฃู ุงูู
Primary KeysูุงููForeign Keysูู ุงููdatabaseุจุชููู ุบุงูุจูุงprimitive types(int,string,Guidโฆ) ูุงููEntity Frameworkุจูุนุฑู ููุงุฑููู ุจุจุนุถ ุนุงุฏู ุฌุฏูุง ู ู ุบูุฑIEqualityComparer. - ุงูู
overloadุฏู ุบุงูุจูุงnot translatedููSQLุจุดูู ุตุญูุญ ูู ุญุงููุช ุชุณุชุฎุฏู ู ู ุนdatabase query.
- ูุฃุ ุบุงูุจูุง ู
ุด ุจูุญุชุงุฌู ุฎุงูุต. ูููุ ูุฃู ุงูู
- ุงูุฎูุงุตุฉ: ุงูุณู ุงูู
overloadุฏู ุฏูููุชูุ ู ุด ููุณุชุฎุฏู ู ู ุน ุงููdatabase.
GroupJoin() Operator (ูุงุณุชุฎุฏุงู
ู ูุนู
ู Left Join)
ููุฌู ุจูู ููู operator ุงูุชุงููุ ุงููู ูู GroupJoin. ุฏู ููู ุงุณุชุฎุฏุงู
ู
ุนูู ูู
ู
ูู ูููู ู
ุฑุจู ุดููุฉ.
ุงุณุชุฎุฏุงู
ุงูู GroupJoin ุงูุฃุณุงุณู (Join ุซู
Grouping by Object)
- ุงูุงุณุชุฎุฏุงู
ุงูุฃุณุงุณู ุฃู ุงูููุฑุฉ ุงูุฃุตููุฉ ูุฑุง
GroupJoinูู ุฅูู ุชุนู ูjoinุจููtwo sequencesุ ูุจุนุฏูู ุชุนู ูgroupingูููุชุงุฆุฌ. - ุงูุชุฑูุฉ ูููุ ุงูู
Groupingุงููู ุจูุนู ููGroupJoinุจููููbased on the entire objectู ู ุงููouter sequenceุ ู ุดbased on a specific column. - ู
ุซุงู: ูู ุนู
ูุช
GroupJoinุจููDepartmentsูEmployeesุ ู ู ูู ุงููุชูุฌุฉ ุชููู ูุฃูู ุจุชููู โูููDepartmentobjectุ ูุงุชูู ูุงูู ุฉ ุจุงููEmployeesุจุชูุนูโ.
ุชุฌุฑุจุฉ ุงูู GroupJoin ู
ุน ุงูู Database (ู
ุดููุฉ ุงูุชุฑุฌู
ุฉ)
ุชุนุงููุง ูุดูู ุดูู ุงูู fluent syntax ุจุชุงุน GroupJoin:
// Example starting with Departments to group by Department object
var groupJoinResult = context.Departments
.GroupJoin(
context.Employees, // Inner sequence (Employees)
d => d.Id, // Outer Key Selector (PK of Department)
e => e.DepartmentId, // Inner Key Selector (FK of Employee)
(d, emps) => new // Result Selector (takes department object, and IEnumerable of matching employees)
{
Department = d, // The Department object itself acts as the key for grouping
Employees = emps // The collection of employees for that department
}
);
// Trying to iterate (this will likely throw an exception when hitting the database)
// foreach (var item in groupJoinResult)
// {
// Console.WriteLine($"Department: {item.Department.Name}");
// foreach (var emp in item.Employees)
// {
// Console.WriteLine($" - Emp: {emp.Name}");
// }
// }ุดุฑุญ ุงูููุฏ:
- ุงูู
context.Departments.GroupJoin(...): ุจูุจุฏุฃ ุจุงููDbSetุงููู ุนุงูุฒูู ูุนู ูgroupingุนูู ุฃุณุงุณ ุงููobjectsุจุชุงุนุชู (ููุงDepartments). - ุงูู
context.Employees,d => d.Id,e => e.DepartmentId: ุฏูู ุฒู ุงููJoinุงูุนุงุฏู (ุงููinner sequenceูุงููkeys). - ุงูู
(d, emps) => new { ... }: ุงููresult selectorููุง ู ุฎุชูู.- ุงูู
parameterุงูุฃูู (d) ุจูู ุซู ุงููobjectู ู ุงููouter sequence(ุงููDepartmentobject). - ุงูู
parameterุงูุชุงูู (emps) ู ุด ุจูู ุซูemployeeูุงุญุฏุ ูุฃ ุฏู ุจูู ุซูIEnumerable<Employee>ุ ูุนูู ูุงูู ุฉ ุจูู ุงููemployeesุงููู ุงููDepartmentIdุจุชุงุนูู ุจูุณุงูู ุงููIdุจุชุงุน ุงููDepartmentุงูุญุงูู (d). - ุฑุฌุนูุง
anonymous typeููู ุงููDepartmentobject ููุณู ูู ุฌู ูุนุฉ ุงููEmployeesุจุชุงุนุชู.
- ุงูู
ุงููุฑู ุจูู Cs IQueryable ู Cs IEnumerableุ
ู ู ุงูุขุฎุฑ ููุง ุงูู GroupJoin ุชุนุชุจุฑ Cs Extension Methods ูู Queryable ุฃู Enumerable ูุงููู ุจููุฐูู ู ู Queryable ุฏู ุจูููุฐ ุงูุฃู ุฑ ูู ุงูู Database ููุฌูุจูู ุงูุฏุงุชุง ุฎูุตุงูุฉ ููุง
ุงูู ุง ุงูู Cs Enumerable ููุฌูุจูู ุงูุฏุงุชุง ูููุง ุนูุฏู ูู ุงูู Memory ููุจุฏุฃ ูููุฐ ุงูู Query ููุง
ุฅูู ุงูู ุดููุฉ ูู ุง ูุดุบู ุงูููุฏ ุฏู ุนูู ุงูู Databaseุ
- ูู
ุง ุงูู
Entity Framework Coreูุญุงูู ูุชุฑุฌู ุงููqueryุฏู ููSQLุ ูููุดู ูููุถุฑุจexceptionุบุงูุจูุง ุจุชูููcould not be translated. - ูููุ ูุฃู
SQLู ููููุด ุญุงุฌุฉ ุงุณู ูุง ูุนู ูgrouping based on a whole recordุฃูobject. ุงููGROUP BYููSQLูุงุฒู ููููbased on specific columns(ุฒูDepartmentNameุฃูDepartmentId). - ูู ุงูุงุณุชุฎุฏุงู
ุงูุฃุณุงุณู ุฏู ููู
GroupJoinู ูููุนุด ูุทุจูู ู ุจุงุดุฑุฉ ุนูู ุงููdatabase.
ุงูุงุณุชุฎุฏุงู ุฏู ูููุน ูููุ
- ูููุน ูู ุดุบุงููู ุนูู
local sequences(ุฒูList<Department>ูList<Employee>ูู ุงูู memory). ุณุงุนุชูุง ุงููLINQ to Objectsูููุฏุฑ ูุนู ูgrouping based on objectุนุงุฏู.
ุงุณุชุฎุฏุงู
ุงูู GroupJoin ูุนู
ู Left Join (ุงูุทุฑููุฉ ุงูุฑุณู
ูุฉ)
ุงูู GroupJoin ููุญุฏู ููู ุงุณุชุฎุฏุงู
ุฃุณุงุณู (ูุนู
ู join ูุจุนุฏูู grouping based on the outer object)ุ ุจุณ ุฒู ู
ุง ูููุงุ ุงูุงุณุชุฎุฏุงู
ุฏู ู
ุด ุจูุชุฑุฌู
ูููุณ ูู SQL.
ุงููุงูุฏุฉ ุงูุญููููุฉ ููู GroupJoin ู
ุน EF Core ูู ุฅูู ุจูููู ุฎุทูุฉ ุฃุณุงุณูุฉ ุนุดุงู ูุนู
ู Left Outer Join.
ุงูู Left Join ุจูุฌูุจ ูู ุนูุงุตุฑ ุงูู sequence ุงูุดู
ุงู (Left)ุ ูุงูุนูุงุตุฑ ุงูู
ุทุงุจูุฉ ูููุง ู
ู ุงูู sequence ุงููู
ูู (Right). ูู ุนูุตุฑ ูู ุงูุดู
ุงู ู
ููุด ู
ูุงุจู ูู ุงููู
ููุ ุจูุฌูุจู ุจุฑุถู ุจุณ ุจูุญุท null (ุฃู default) ู
ูุงู ููู
ุงููู
ูู.
ู
ููุด method ู
ุจุงุดุฑุฉ ุงุณู
ูุง .LeftJoin() ูู LINQ ุงูููุงุณู ููุฏุฑ ูุณุชุฎุฏู
ูุง ู
ุน EF Core. ุจูุนู
ููุง ุจุงุณุชุฎุฏุงู
GroupJoin ู
ุน SelectMany ู DefaultIfEmpty.
ุนู
ู Left Join ุจู Query Syntax (ุจุงุณุชุฎุฏุงู
into) - ุงูุฃุณูู ูููุฑุงุกุฉ
ุงูุทุฑููุฉ ุฏู ูู ุงูุฃูุถุญ ูุนู
ู Left Join:
Console.WriteLine("\n--- Left Join (Query Syntax using 'into') ---");
// Get ALL Departments, and their corresponding Employees (or null if none)
var leftJoinQuery =
from dept in context.Departments // Start with the LEFT table (Departments)
join emp in context.Employees // Join with the RIGHT table (Employees)
on dept.Id equals emp.DepartmentId // Join condition
into empGroup // *** Use 'into' to put matching employees into a temporary group ***
from employeeInGroup in empGroup.DefaultIfEmpty() // *** Iterate the group, use DefaultIfEmpty() for departments with no employees ***
select new
{
DepartmentName = dept.Name,
// EmployeeName will be null if employeeInGroup is null (due to DefaultIfEmpty)
EmployeeName = employeeInGroup == null ? "!!No Employees!!" : employeeInGroup.Name
};
// Execute and display
// foreach (var item in leftJoinQuery)
// {
// Console.WriteLine($"Department: {item.DepartmentName}, Employee: {item.EmployeeName}");
// }
Console.WriteLine("(Query would fetch all departments and their employees, showing 'No Employees' for empty depts)");
ุดุฑุญ ุงูู Magic:
- ุงูู
from dept ... join emp ... on ...: ุฒู ุงููInner Joinุนุงุฏู. - ุงูู
into empGroup: ุฏู ุฃูู ุญุชุฉ. ุจุฏู ู ุง ุงููjoinูุฑุฌุน (dept, emp) ููู ู ุงุชุดุ ุจููููู ุญุท ูู ุงููempุงููู ุจููุงุจููุง ุงููdeptุฏู ูู ู ุฌู ูุนุฉ ู ุคูุชุฉ ุงุณู ูุงempGroup. ุงููempGroupุฏู ูููููIEnumerable<Employee>. - ุงูู
from employeeInGroup in empGroup.DefaultIfEmpty(): ุจูุนู ูloopุชุงููุฉ ุนูู ุงููempGroupุฏู.- ุงูู
DefaultIfEmpty(): ุฏู ุจุชุนู ู ุฅููุ ูู ุงููempGroupูุงู ูุงุถู (ูุนูู ุงููุณู ุฏู ู ููุด ููู ู ูุธููู ูู ุงููjoin)ุ ุงููmethodุฏู ุจุชุฑุฌุนsequenceูููุง ุนูุตุฑ ูุงุญุฏ ุจุณ ููู ุชูnull(ุฃู ุงููdefaultุจุชุงุนEmployee). ูู ุงููempGroupู ุด ูุงุถูุ ุจุชุฑุฌุนู ุฒู ู ุง ูู. - ููู
ุง ูุนู
ู
from employeeInGroup in ...ุ ูู ุงููุณู ููู ู ูุธูููุ ุงููloopูุชูู ุนูู ูู ู ูุธู ูemployeeInGroupููุจูู ูู ุงูู ูุธู ุฏู. ูู ุงููุณู ู ููููุด ู ูุธูููุ ุงููloopูุชูู ู ุฑุฉ ูุงุญุฏุฉ ุจุณ ูemployeeInGroupููุจูู ููู ุชูnull.
- ุงูู
- ุงูู
select new { ... }: ุจูุฎุชุงุฑ ุงููุชูุฌุฉ. ุงููdept.Nameุฌุงู ู ู ุงููfromุงูุฃููู. ุงููEmployeeNameุจูุงุฎุฏู ู ูemployeeInGroupุ ุจุณ ูุงุฒู ูุนู ูcheckุฅูู ู ุดnullุงูุฃูู.
ุนู
ู Left Join ุจู Fluent Syntax (ุจุงุณุชุฎุฏุงู
GroupJoin().SelectMany())
ุงูุทุฑููุฉ ุฏู ุจุชุงุฏู ููุณ ุงูุบุฑุถุ ุจุณ ุงูู syntax ุจุชุงุนูุง ุฃุนูุฏ ุดููุฉ:
Console.WriteLine("\n--- Left Join (Fluent Syntax using GroupJoin + SelectMany) ---");
var leftJoinFluent = context.Departments // Start with LEFT table
.GroupJoin( // Step 1: GroupJoin
context.Employees, // Right table
dept => dept.Id, // Outer Key (Left)
emp => emp.DepartmentId, // Inner Key (Right)
(dept, empGroup) => new { Department = dept, Employees = empGroup } // Project to {Dept, GroupOfEmps}
)
.SelectMany( // Step 2: Flatten using SelectMany and handle empty groups
deptAndGroup => deptAndGroup.Employees.DefaultIfEmpty(), // Apply DefaultIfEmpty to the employee group
(deptAndGroup, employeeInGroup) => new // Result selector for SelectMany
{
DepartmentName = deptAndGroup.Department.Name,
EmployeeName = employeeInGroup == null ? "!!No Employees!!" : employeeInGroup.Name
}
);
// Execute and display (same result as Query Syntax)
// foreach (var item in leftJoinFluent)
// {
// Console.WriteLine($"Department: {item.DepartmentName}, Employee: {item.EmployeeName}");
// }
Console.WriteLine("(Query would fetch all departments and their employees, showing 'No Employees' for empty depts)");ุดุฑุญ:
- ุจูุจุฏุฃ ุจู
GroupJoinุฒู ู ุง ุนู ููุงู ูุจู ูุฏูุ ุจูุฑุฌุนsequenceู ู{Department, EmployeesGroup}. - ุจูุณุชุฎุฏู
SelectManyุนุดุงู ูุนู ูflatten. - ุงูุฌุฒุก ุงูุฃูู ู
ู
SelectMany(deptAndGroup => deptAndGroup.Employees.DefaultIfEmpty()) ุจูุงุฎุฏ ููgroupู ู ุงูู ูุธูููุ ููู ูุงุถูุฉ ุจูุฑุฌุนsequenceูููุงnull. - ุงูุฌุฒุก ุงูุชุงูู ู
ู
SelectMany((deptAndGroup, employeeInGroup) => new { ... }) ุจูุงุฎุฏ ุงููobjectุงูุฃุตูู (deptAndGroup) ูุจูุงุฎุฏ ูู ุนูุตุฑ ู ู ูุชูุฌุฉ ุงููDefaultIfEmpty(ุงููู ูู ูุงEmployeeูุงnull)ุ ูุจูุนู ูselectูููุชูุฌุฉ ุงูููุงุฆูุฉ.
ุงูุฎูุงุตุฉ ููู Left Join: ุงูู Query Syntax ุจุงุณุชุฎุฏุงู
into ุบุงูุจูุง ุจุชููู ุฃุณูู ูุฃูุถุญ ุจูุชูุฑ ู
ู ุงูู Fluent Syntax ุจุงุณุชุฎุฏุงู
GroupJoin().SelectMany().
Cross Join (Cartesian Product)
ุงูู Cross Join ุจูุฌูุจ ูู ุงูุงุญุชู
ุงูุงุช ุงูู
ู
ููุฉ ุจูู ู
ุฌู
ูุนุชููุ ูุนูู ูู ุนูุตุฑ ู
ู ุงูุฃููู ู
ุน ูู ุนูุตุฑ ู
ู ุงูุชุงููุฉ. (ุงุณุชุฎุฏุงู
ุงุชู ููููุฉ ูู ุงูู Business).
ุนู
ู Cross Join ุจู Query Syntax (ุงุชููู from)
ุงูุทุฑููุฉ ุจุณูุทุฉ ุฌุฏูุง: ู
ุฌุฑุฏ ุงุชููู from ูุฑุง ุจุนุถ ู
ู ุบูุฑ join ุฃู where ุจูููู
.
Console.WriteLine("\n--- Cross Join (Query Syntax) ---");
// Get every possible combination of Employee and Department
var crossJoinQuery =
from emp in context.Employees // First sequence
from dept in context.Departments // Second sequence (NO 'join' or 'on')
select new
{
EmployeeName = emp.Name,
DepartmentName = dept.Name
};
// Execute and display
// foreach (var item in crossJoinQuery)
// {
// Console.WriteLine($"Employee: {item.EmployeeName}, Department: {item.DepartmentName}");
// }
Console.WriteLine("(Query would fetch all combinations of employees and departments)");
ุนู
ู Cross Join ุจู Fluent Syntax (SelectMany)
ุงูู Fluent Syntax ุงูู
ูุงูุฆ ูุงุชููู from ูู ุบุงูุจูุง SelectMany.
Console.WriteLine("\n--- Cross Join (Fluent Syntax) ---");
var crossJoinFluent = context.Employees // Start with first sequence
.SelectMany(
emp => context.Departments, // For each employee, the collection to cross with is ALL departments
(emp, dept) => new // Result selector combining employee and department
{
EmployeeName = emp.Name,
DepartmentName = dept.Name
}
);
// Alternative SelectMany structure (achieves the same)
var crossJoinFluentAlt = context.Employees
.SelectMany(emp => context.Departments.Select(dept => new { emp, dept })) // Create pairs first
.Select(pair => new { EmployeeName = pair.emp.Name, DepartmentName = pair.dept.Name }); // Select final
// Execute and display (same result as Query Syntax)
// foreach (var item in crossJoinFluent)
// {
// Console.WriteLine($"Employee: {item.EmployeeName}, Department: {item.DepartmentName}");
// }
Console.WriteLine("(Query would fetch all combinations of employees and departments)");
ุงูุฎูุงุตุฉ ููู Cross Join: ุงูู Query Syntax (ุงุชููู from) ุจุชููู ุฃูุถุญ ูุฃุณูู ูู ุงููุฑุงุกุฉ.
ููุทุฉ ุฃุฎูุฑุฉ: ุงู
ุชู ุฃุณุชุฎุฏู
Join ุตุฑูุญุฉ ุจุฏู .Include() ููู Manyุ (ุนุดุงู ุงูู Performance)
ูุฑุฌุน ุชุงูู ูููุทุฉ ุงูู Eager Loading (.Include()) ููู Navigational Property Many (ุฒู ุญุงูุฉ Order ู OrderItems ุงููู ูููุง ูุงุฒู
ูุนู
ููุง Eager Loading).
- ูู
ุง ุจูุณุชุฎุฏู
.Include()ู ุนNavigational Property Manyุ ุงููEntity Framework Coreุจูุชุฑุฌู ูุง ููSQL. ุฃุญูุงููุง (ู ุด ุฏุงูู ูุง)ุ ุงููSQLุงููุงุชุฌ ุฏู ู ู ูู ู ููููุด ุงูุฃู ุซู ู ู ูุงุญูุฉ ุงููperformance. ู ู ูู ูุญุชูู ุนููjoinูู ุนุงูุงsubqueryุฃู ุทุฑููุฉ ุงููjoinููุณูุง ู ุชูููุด ุงูุฃูุถู. - ุงูุญู (ูู ุญุงูุงุช ูุงุฏุฑุฉ ุฌุฏูุง ูู ุงูู
Performancecriticalุฃูู):- ุจุฏู ู
ุง ุชุณุชุฎุฏู
.Include(o => o.OrderItems)ุ ู ู ูู ุชูุชุจ ุงููJoinุจููOrdersูOrderItemsุจุฅูุฏู (ุจุงุณุชุฎุฏุงูJoinoperator ุฒู ู ุง ุดุฑุญูุง ูู ุงูุฃูู). - ูููุ ุฏู ู
ู
ูู ูุฏู ุงูู
database query optimizerุญุฑูุฉ ุฃูุจุฑ ุฅูู ูุฎุชุงุฑ ุทุฑููุฉ ุงููjoinุงูุฃูุถูุ ุฃู ูุชุฌูุจ ุงููsubqueryุงููู ู ู ูู.Include()ุชุนู ูู. - ุชุญุฐูุฑ: ุฏู ุชุนุชุจุฑ
advanced optimization. ู ุชุนู ููุงุด ุบูุฑ ูู ุฃูุช ู ุชุฃูุฏ ุฅู.Include()ุนุงู ู ู ุดููุฉperformanceุญููููุฉ ููุณุช ุงููุฑู ุจููุณู. ูู ู ุนุธู ุงูุญุงูุงุชุ.Include()ุจูููู ูุงูู ูู ูุฑูุก ุฃูุชุฑ.
- ุจุฏู ู
ุง ุชุณุชุฎุฏู
ู ุนููู ุงุช ุฅุถุงููุฉ (More Information)
let Keyword
- ุจูุณุชุฎุฏู
letุฌูู ุงููQuery Syntaxุนุดุงู ูุนุฑูvariableู ุคูุช ููุฏุฑ ูุฎุฒู ููู ูุชูุฌุฉ ุนู ููุฉ ุญุณุงุจูุฉ ุฃูsub-expressionุนุดุงู ูุณุชุฎุฏู ูุง ุฃูุชุฑ ู ู ู ุฑุฉ ูู ููุณ ุงููqueryุฃู ุนุดุงู ูุฎููู ู ูุฑูุก ุฃูุชุฑ. - ุงูู
variableุฏู ุจูููู ู ุชุงุญ ูู ุจุงูู ุฃุฌุฒุงุก ุงููqueryุงููู ุจุชูุฌู ุจุนุฏ ุงููlet(ุฒูwhereุฃูorderbyุฃูselect).
ู ุซุงู: ูุงุช ุฃุณู ุงุก ุงูู ูุธููู ุงููู ุงุณู ูู (ุจุนุฏ ุชุญูููู ูู uppercase) ุจูุจุฏุฃ ุจุญุฑู โAโุ ูุฑุชุจูู ุจุงูุงุณู ุงูู uppercase ุฏู.
// Using 'let' in Query Syntax
var queryWithLet =
from e in employees
let upperCaseName = e.Name.ToUpper() // Define temporary variable
where upperCaseName.StartsWith("A") // Use the variable
orderby upperCaseName // Use the variable again
select upperCaseName; // Select the variable
Console.WriteLine("\nQuery with 'let':");
Console.WriteLine(string.Join(", ", queryWithLet)); // AHMED, ALIinto Keyword
ุงุชููู
ูุง ุนููุง ููู ู
ุน group by ู join. ุงุณุชุฎุฏุงู
ูุง ุงูุฃุณุงุณู ูู ุฅููุง ุจุชูู
ู ุงูู query ุจุนุฏ ู
ุฑุญูุฉ ู
ุนููุฉ (ุฒู group ุฃู join)ุ ูุจุชุนุฑู variable ุฌุฏูุฏ ููู
ุฑุญูุฉ ุงูุฌุฏูุฏุฉ ุฏู. ูุฃููุง ุจุชุนู
ู restart ููู query ุจุณ ุจุงููุชูุฌุฉ ุงูู
ุคูุชุฉ ุงููู ูุตูุช ููุง.
- ู
ุน
group by ... into groupVariable: ุจููู ู ุดุบู ุนูู ุงููgroupsุงููู ุงุชูููุช. - ู
ุน
join ... into groupVariable: ุจููู ู ุดุบู ุนูู ุงููgroupsุงููู ุงุชูููุช ุถู ูููุง ุนุดุงู ูุนู ู ุบุงูุจูุงLeft Join. - ู
ุน
select ... into variable: ู ู ูู ุชุณุชุฎุฏู ูุง ุนุดุงู ุชุงุฎุฏ ูุชูุฌุฉselectูุชูู ู ุนูููุงqueryุชุงููุ ุจุณ ุฏู ุงุณุชุฎุฏุงู ูุง ุฃูู ุดููุนูุง ูุฅููุง ู ู ูู ูุนู ูchainingุจุงููFluent Syntaxุฃุณูู.
ุงููุฑู ุจูู let ู into:
- ุงูู
let: ุจุชุนุฑูvariableุฌูู ููุณ ุงููquery scopeุนุดุงู ุชุณุชุฎุฏู ู ูู ุงูุฃุฌุฒุงุก ุงููู ุจุงููุฉ ู ู ุงููqueryุฏู. ุจุชูู ู ุงููqueryุจููุณ ุงููrange variableุงูุฃุตูู + ุงููvariableุงูุฌุฏูุฏ. - ุงูู
into: ุจุชููู ุงููquery scopeุงูุญุงูู ูุชุจุฏุฃscopeุฌุฏูุฏ ุจุงููุชูุฌุฉ ุงููู ูุตูุช ููุง. ุงููrange variablesุงููู ูุงูุช ูุจูinto(ู ุง ุนุฏุง ุงููู ูู ุฌู ูุฉintoููุณูุง) ู ุจุชุจูุงุด ู ุชุงุญุฉ ุจุนุฏinto. ูุฃููุง ุจุชุนู ูrestartูููquery.
ุงุณุชุฎุฏุงู Regex ู ุน LINQ
ู
ู
ูู ูุณุชุฎุฏู
Regular Expressions (ุงููู ุงุชููู
ูุง ุนููุง ูุจู ูุฏู) ุฌูู LINQ queries (ุฎุตูุตูุง ู
ุน Select ุฃู Where) ุนุดุงู ูุนู
ู ุนู
ููุงุช ู
ุนูุฏุฉ ุนูู ุงูู strings.
ู ุซุงู: ุดูู ูู ุงูุญุฑูู ุงูู ุชุญุฑูุฉ (vowels) ู ู ุฃุณู ุงุก ุงูู ูุธููู.
using System.Text.RegularExpressions; // Need this namespace
Console.WriteLine("\nUsing Regex with LINQ:");
List<string> namesList = employees.Select(e => e.Name).ToList(); // Get names
// Select names without vowels using Regex.Replace
var namesWithoutVowels = namesList.Select(name => Regex.Replace(name, "[aeiouAEIOU]", ""));
Console.WriteLine("Names without vowels:");
Console.WriteLine(string.Join(", ", namesWithoutVowels)); // Ahmd, Mn, Al, Sr
// Example: Filter names that become longer than 3 chars AFTER removing vowels using 'let'
var longNamesAfterNoVowelsLet =
from name in namesList
let noVowelName = Regex.Replace(name, "[aeiouAEIOU]", "")
where noVowelName.Length > 3 // Check length of the result
select noVowelName;
Console.WriteLine("\nLong names (>3) after removing vowels (let):");
Console.WriteLine(string.Join(", ", longNamesAfterNoVowelsLet)); // Ahmd
// Example: Filter names that become longer than 3 chars AFTER removing vowels using 'into'
var longNamesAfterNoVowelsInto =
from name in namesList
select Regex.Replace(name, "[aeiouAEIOU]", "") // Select the modified name
into noVowelName // Put result into new variable, restarting query scope
where noVowelName.Length > 3 // Filter based on the new variable
select noVowelName;
Console.WriteLine("\nLong names (>3) after removing vowels (into):");
Console.WriteLine(string.Join(", ", longNamesAfterNoVowelsInto)); // Ahmd
// Equivalent using Fluent Syntax (often simpler here)
var longNamesAfterNoVowelsFluent = namesList
.Select(name => Regex.Replace(name, "[aeiouAEIOU]", "")) // Transform
.Where(noVowelName => noVowelName.Length > 3); // Filter
Console.WriteLine("\nLong names (>3) after removing vowels (Fluent):");
Console.WriteLine(string.Join(", ", longNamesAfterNoVowelsFluent)); // Ahmdูู ุงูุญุงูุฉ ุฏูุ ุงุณุชุฎุฏุงู
Fluent Syntax ุฃู Query Syntax ู
ุน let ุจูููู ุบุงูุจูุง ุฃุณูู ู
ู ุงุณุชุฎุฏุงู
into.
ุงูููุงูุฉ (End)
- ุฑุงุฌุน ุงูู documentation ุงูุฑุณู ู.
- ุญู ุชู ุงุฑูู (ุฒู ุฏู ุนูู Northwind database).
- ู ู ูู ุชุจุต ุนูู ู ูุฎุตุงุช ุฒู LINQ Summary.pdf (ูู ู ุชุงุญ).
- ุงุจุญุซ ุนู ุชู ุงุฑูู ุชุงููุฉ ุฒู w3resource LINQ exercises.