Entity Framework Core常見語法介紹
今天要來學的是EF Core中常見的語法們~想知道怎麼查EF Core資料庫看這篇就對惹✨
❇️無條件查詢所有資料
以下是查詢Products、Employees、Orders所有資料的語法,也列出了同步及非同步兩種形式,而在.NET(Core)中建議以非同步為主。
🔗Controller/ProductsController.cs
public async Task<IActionResult> QueryAllData()
{
// Asynchronous
List<Products> products = await _context.Products.ToListAsync();
var employees = await _context.Employees.ToListAsync();
// Synchronous
List<Orders> orders = _context.Orders.ToList();
var orderDetails = _context.OrderDetails.ToList();
return View(employees);
}
❇️用First和Single方法查詢單一筆資料
First()、FirstOrDefault()、Single()、SingleOrDefault()四個方法皆是回傳同一筆資料,但有差異,差異如下表:
💡First與Single方法回傳之比較
在資料來源不為null,且含有資料成員的情況下,以下是first與FirstOrDefault方法之比較⬇️
1.回傳序列有一或多筆資料:First與FirstOrDefault皆回傳第一筆資料。
2.回傳序列無資料:
First方法➡️擲出InvalidOperationException例外
FirstOrDefault方法➡️回傳預設值Single與SingleOrDefault方法之比較⬇️
1.回傳序列只有一筆資料:Single與SingleOrDefault皆回傳該筆唯一資料。
2.回傳序列有多筆資料:Single與SingleOrDefault皆會擲出InvalidOperationException例外。
3.回傳序列若無資料:
Single方法➡️擲出InvalidOperationException例外
SingleOrDefault方法➡️回傳預設值
❇️以特定條件查詢資料
在Where中以特定條件查詢、排序,同時列出Query Syntax與Method Query兩種查詢方法。
🔗Controller/ProductsController.cs
public async Task<IActionResult> FilteringData()
{
// Query Syntax 查詢語法
var p1 = await (from p in _context.Products
where p.UnitPrice >= 10 && p.UnitPrice <= 15
orderby p.ProductName, p.UnitPrice
select p).ToListAsync();
// Method Syntax 方法語法
var p2 = await _context.Products
.Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
.OrderBy(p => p.ProductName)
.ThenBy(p => p.UnitPrice)
.ToListAsync();
// 同步查詢語法
var p3 = (from p in _context.Products
where p.UnitPrice >= 10 && p.UnitPrice < 15
orderby p.ProductName descending, p.UnitPrice ascending
select p).ToList();
// 使用 AsEnumerable() 來轉換成 IEnumerable<Product>
var p4 = _context.Products
.AsEnumerable()
.Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
.OrderByDescending(p => p.ProductName)
.ThenByDescending(p => p.UnitPrice)
.ToList();
// 使用 AsQueryable() 來轉換成 IQueryable<Product>
var p5 = _context.Products
.AsQueryable()
.Where(p => p.UnitPrice >= 10 && p.UnitPrice <= 15)
.OrderByDescending(p => p.ProductName)
.ThenByDescending(p => p.UnitPrice)
.ToList(); // 匿名排序
return View(p1); // 回傳 p1 給 View
}
❇️多個資料表的Inner Join查詢
前面所談的都是針對單一資料表,但真的在使用上一般都是多個資料表間的關聯查詢。
以下是Inner Join查詢語法⬇️
public async Task<IActionResult> TablesJoin()
{
//1. 兩表聯合查詢 - 匿名示例
var innerJoin1 = from cate in _context.Categories
join prod in _context.Products on cate.CategoryId equals prod.CategoryId
select new { Name = prod.ProductName, Category = cate.CategoryName };
// 獲取LINQ轉換的SQL語句
string sql = innerJoin1.ToQueryString();
//2. 兩表聯合查詢 - 匿名示例
var innerJoin2 = from cate in _context.Set<Category>()
join prod in _context.Set<Product>() on cate.CategoryId equals prod.CategoryId
select new { Name = prod.ProductName, Category = cate.CategoryName };
//3. 三表聯合查詢 - 使用OrdersViewModel強類型
var innerJoin3 = from orders in _context.Orders.TagWith("3 Tables join")
join details in _context.OrderDetails on orders.OrderId equals details.OrderId
join prods in _context.Products on details.ProductId equals prods.ProductId
select new OrdersViewModel {
ProductId = details.ProductId,
ProductName = prods.ProductName,
OrderId = orders.OrderId,
UnitPrice = details.UnitPrice,
OrderDate = orders.OrderDate,
ShipAddress = orders.ShipAddress,
ShipCity = orders.ShipCity,
ShipCountry = orders.ShipCountry
};
//4. 四表聯合查詢 - 匿名示例
var innerJoin4 = from customer in _context.Customers.TagWith("4 Tables join")
join order in _context.Orders on customer.CustomerId equals order.CustomerId
join details in _context.OrderDetails on order.OrderId equals details.OrderId
join prod in _context.Products on details.ProductId equals prod.ProductId
select new {
order.OrderId,
customer.CompanyName,
customer.ContactName,
details.ProductId,
prod.ProductName,
details.UnitPrice,
details.Quantity
};
var result = await innerJoin4.ToListAsync();
return Json(result);
//string json = Newtonsoft.Json.JsonConvert.SerializeObject(result);
//return Content(json, "application/json");
}
❇️Skip與Take方法
public async Task<IActionResult> SkipTake()
{
var products = from p in _context.Products
where p.UnitPrice >= 10 && p.UnitPrice <= 15
orderby p.ProductName descending, p.UnitPrice ascending
select p;
// Skip(5) 跳過前 5 筆,然後 Take(10) 取 10 筆
var query = await products.Skip(5).Take(10).ToListAsync();
return View(query);
}
❇️IQuerable< T >與IEnumerable< T >與ToList()
public IActionResult QueryType()
{
// 1. Lazy Loading 延後執行
// 使用解析 Expression 將轉成實際呼叫的 SQL 語法,當回傳必要資料再執行查詢
IQueryable<Product> products = _context.Products.TagWith("[Queryable]")
.Where(p => p.UnitPrice > 10);
}
foreach (var i in products)
{
Console.WriteLine($"{i.ProductId}, {i.ProductName}, {i.UnitPrice}, {i.UnitsInStock}");
}
// 2. 延遲加載:將資料全部取出之後再轉換成 IEnumerable 並進行篩選操作
IEnumerable<Product> prods = _context.Products.TagWith("[IEnumerable]")
.AsEnumerable()
.Where(p => p.UnitPrice > 20);
// 將篩選後的資料轉換為列表並逐一輸出
prods.ToList().ForEach(p => { Console.WriteLine($"{p.ProductId}, {p.ProductName}, {p.UnitPrice}, {p.UnitsInStock}"); });
// 3. 立即加載:將資料轉換成 List<T>,立即執行查詢並將結果載入到記憶體中
List<Product> prodList = _context.Products.TagWith("[ToList()]")
.Where(p => p.UnitPrice > 30)
.ToList();
// 4. 加載 OrderDetails 導覽屬性:同時取出每個產品的相關訂單明細資料
var pds = _context.Products
.Where(p => p.UnitPrice > 40)
.Include(p => p.OrderDetails)
.ToList();
// 將列表轉換為 JSON,並設定避免參考循環的處理方式
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string json = JsonConvert.SerializeObject(pds);
return View(products);
❇️使用原生SQL查詢
❇️執行Update及Delete非查詢類的SQL語法
那麼以上就是今天的分享啦~
明天見啦~See YA(。•̀ᴗ-)