# C#LINQ (微SQL)
類似於用來查詢、篩選、排序和處理資料集合的東西
上面的都是C#程式,下面的是SQL有進行標示
>ChatGPT資料整理
[TOC]
## 基本 LINQ 語法 (from ... where ... select ...)
* from:指定資料來源 (from p in products)
* where:過濾條件 (where p.Price > 500)
* select:選擇回傳的資料 (select p.Name)
```csharp=
var result = from 變數 in 集合
where 條件
select 變數;
```
### 簡單應用:
products是一個集合,裡面有需多資料
p將資料提取出來進行比對,如果>100就加入資料
```csharp=
var result = from p in products
where p.Price > 100
select p;
```
```csharp=
// 移除空格或非數字字符
cardNumber = new string(cardNumber.Where(char.IsDigit).ToArray());
```
SQL
```sql=
SELECT * FROM Products WHERE Price > 100;
```
## LINQ to Objects(list、array)
```csharp=
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// 取出所有偶數
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
```
n=>n 為將n傳入到(=>)另一端n
再進行條件判斷n % 2 == 0
SQL
```sql=
SELECT * FROM Numbers WHERE Number % 2 = 0;
```
## LINQ to DataTable
```csharp=
var query = from row in dataTable.AsEnumerable()
where row.Field<int>("Age") > 30
select row;
```
SQL
```sql=
SELECT * FROM dataTable WHERE Age > 30;
```
## Select 選取特定欄位
```csharp=
var productNames = products.Select(p => p.Name).ToList();
```
SQL
```sql=
SELECT Name FROM Products;
```
## OrderBy 排序
### 順序排序
```csharp=
var sortedProducts = products.OrderBy(p => p.Price).ToList();
```
SQL
```sql=
SELECT * FROM Products ORDER BY Price;
```
### 降序排序
```csharp=
var sortedProductsDesc = products.OrderByDescending(p => p.Price).ToList();
```
SQL
```sql=
SELECT * FROM Products ORDER BY Price DESC;
```
## GroupBy 群組
```csharp=
var groupedProducts = products.GroupBy(p => p.Category)
.Select(g => new { Category = g.Key, Count = g.Count() })
.ToList();
```
SQL
```sql=
SELECT Category, COUNT(*) FROM Products GROUP BY Category;
```
## Join 兩個表格關聯
```csharp=
var query = from p in products
join c in categories on p.CategoryId equals c.Id
select new { p.Name, c.CategoryName };
```
SQL
```sql=
SELECT p.Name, c.CategoryName FROM Products p
JOIN Categories c ON p.CategoryId = c.Id;
```
## FirstOrDefault 取得第一筆
```csharp=
var product = products.FirstOrDefault(p => p.Name == "Laptop");
```
SQL
```sql=
SELECT TOP 1 * FROM Products WHERE Name = 'Laptop';
```
## Any 檢查是否有符合條件的資料
* 若有至少一個符合條件的元素 → Any() 回傳 true
* 若沒有符合條件的元素 → Any() 回傳 false
```csharp=
bool hasExpensiveProduct = products.Any(p => p.Price > 1000);
```
SQL
```sql=
SELECT CASE WHEN EXISTS (SELECT * FROM Products WHERE Price > 1000) THEN 1 ELSE 0 END;
```
## Count 計算數量
取出 大於100值 的資料數量
```csharp=
int count = products.Count(p => p.Price > 100);
```
SQL
```sql=
SELECT COUNT(*) FROM Products WHERE Price > 100;
```
## 分頁 Skip 和 Take
分頁 ,幫助你從資料庫中 跳過前 n 筆資料並取得 m 筆資料。
* Skip(n):跳過前 n 筆資料。
* Take(m):從目前查詢的結果中,取出最多 m 筆資料。
✅ 例 1:簡單用法
```csharp=
var users = db.Users
.OrderBy(x => x.Id) // 先排序,確保跳過的順序一致
.Skip(5) // 跳過前 5 筆
.Take(10) // 取出 10 筆
.ToList();
```
這樣你會拿到 第 6 到第 15 筆資料。
1. 跳過前 5 筆資料
1. 取出 10 筆資料
✅ 例 2:分頁用法
* pageSize (每頁顯示的筆數)
* pageNumber (當前頁數)
如果你想取得 第 pageNumber 頁的資料,每頁 pageSize 筆:
```csharp=
int pageSize = 10; // 每頁 10 筆
int pageNumber = 2; // 取得第 2 頁
var users = db.Users
.OrderBy(x => x.Id) // 先排序,確保資料順序固定
.Skip((pageNumber - 1) * pageSize) // 跳過前 (頁數 - 1) * 每頁筆數
.Take(pageSize) // 取出 pageSize 筆資料
.ToList();
```
這樣會取得第 11 到第 20 筆資料。
📌 公式:
```scss=
Skip((pageNumber - 1) * pageSize) -> 跳過前幾頁的所有資料
Take(pageSize) -> 取出當前頁的資料
```
✅ 例 3:應用在 ASP.NET Core API
如果你要 建立一個 API 來支援前端分頁,可以這樣寫:
```csharp=
[HttpGet("users")]
public IActionResult GetUsers(int pageNumber = 1, int pageSize = 10)
{
var users = db.Users
.OrderBy(x => x.Id)
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToList();
return Ok(users);
}
```
* pageNumber = 1 時,取 第 1 到 10 筆資料
* pageNumber = 2 時,取 第 11 到 20 筆資料
* 依此類推...
✅ 例 4:搭配 Where 條件篩選
如果你想要 查詢某個條件,然後再分頁:
```csharp=
var users = db.Users
.Where(x => x.Age > 18) // 只查詢年齡大於 18 的使用者
.OrderBy(x => x.Name) // 依照 Name 排序
.Skip(10) // 跳過前 10 筆
.Take(5) // 取出 5 筆
.ToList();
```
這樣你會取得 符合條件的使用者,並跳過前 10 筆後,取出 5 筆。
SQL
```sql=
SELECT *
FROM Users
ORDER BY Id ASC
OFFSET 10 ROWS -- 跳過前 10 筆
FETCH NEXT 5 ROWS ONLY; -- 取出 5 筆
```