2022-09-19 15:16:37 +02:00
|
|
|
|
using Microsoft.EntityFrameworkCore; // ExecuteUpdate, ExecuteDelete
|
|
|
|
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking; // EntityEntry<T>
|
2022-03-05 16:45:55 +01:00
|
|
|
|
using Microsoft.EntityFrameworkCore.Storage; // IDbContextTransaction
|
2022-09-19 15:16:37 +02:00
|
|
|
|
using Packt.Shared; // Northwind, Product
|
2022-03-05 16:45:55 +01:00
|
|
|
|
|
|
|
|
|
|
partial class Program
|
|
|
|
|
|
{
|
2022-09-19 15:16:37 +02:00
|
|
|
|
static void ListProducts(int[]? productIdsToHighlight = null)
|
2022-03-05 16:45:55 +01:00
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
2022-08-17 17:53:29 +02:00
|
|
|
|
if ((db.Products is null) || (!db.Products.Any()))
|
2022-03-05 16:45:55 +01:00
|
|
|
|
{
|
|
|
|
|
|
Fail("There are no products.");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WriteLine("| {0,-3} | {1,-35} | {2,8} | {3,5} | {4} |",
|
|
|
|
|
|
"Id", "Product Name", "Cost", "Stock", "Disc.");
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Product p in db.Products)
|
|
|
|
|
|
{
|
|
|
|
|
|
ConsoleColor previousColor = ForegroundColor;
|
|
|
|
|
|
|
2022-09-19 15:16:37 +02:00
|
|
|
|
if ((productIdsToHighlight is not null) &&
|
|
|
|
|
|
productIdsToHighlight.Contains(p.ProductId))
|
2022-03-05 16:45:55 +01:00
|
|
|
|
{
|
|
|
|
|
|
ForegroundColor = ConsoleColor.Green;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
WriteLine("| {0:000} | {1,-35} | {2,8:$#,##0.00} | {3,5} | {4} |",
|
|
|
|
|
|
p.ProductId, p.ProductName, p.Cost, p.Stock, p.Discontinued);
|
|
|
|
|
|
|
|
|
|
|
|
ForegroundColor = previousColor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static (int affected, int productId) AddProduct(
|
|
|
|
|
|
int categoryId, string productName, decimal? price)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
2022-09-19 15:16:37 +02:00
|
|
|
|
if (db.Products is null) return (0, 0);
|
|
|
|
|
|
|
2022-03-05 16:45:55 +01:00
|
|
|
|
Product p = new()
|
|
|
|
|
|
{
|
|
|
|
|
|
CategoryId = categoryId,
|
|
|
|
|
|
ProductName = productName,
|
|
|
|
|
|
Cost = price,
|
|
|
|
|
|
Stock = 72
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// set product as added in change tracking
|
|
|
|
|
|
EntityEntry<Product> entity = db.Products.Add(p);
|
|
|
|
|
|
WriteLine($"State: {entity.State}, ProductId: {p.ProductId}");
|
|
|
|
|
|
|
|
|
|
|
|
// save tracked change to database
|
|
|
|
|
|
int affected = db.SaveChanges();
|
|
|
|
|
|
WriteLine($"State: {entity.State}, ProductId: {p.ProductId}");
|
|
|
|
|
|
|
|
|
|
|
|
return (affected, p.ProductId);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static (int affected, int productId) IncreaseProductPrice(
|
|
|
|
|
|
string productNameStartsWith, decimal amount)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
2022-09-19 15:16:37 +02:00
|
|
|
|
if (db.Products is null) return (0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Get the first product whose name starts with name.
|
2022-03-05 16:45:55 +01:00
|
|
|
|
Product updateProduct = db.Products.First(
|
|
|
|
|
|
p => p.ProductName.StartsWith(productNameStartsWith));
|
|
|
|
|
|
|
|
|
|
|
|
updateProduct.Cost += amount;
|
|
|
|
|
|
|
|
|
|
|
|
int affected = db.SaveChanges();
|
|
|
|
|
|
|
|
|
|
|
|
return (affected, updateProduct.ProductId);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int DeleteProducts(string productNameStartsWith)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
|
|
|
|
|
using (IDbContextTransaction t = db.Database.BeginTransaction())
|
|
|
|
|
|
{
|
|
|
|
|
|
WriteLine("Transaction isolation level: {0}",
|
|
|
|
|
|
arg0: t.GetDbTransaction().IsolationLevel);
|
|
|
|
|
|
|
|
|
|
|
|
IQueryable<Product>? products = db.Products?.Where(
|
2022-09-19 15:16:37 +02:00
|
|
|
|
p => p.ProductName.StartsWith(productNameStartsWith));
|
2022-03-05 16:45:55 +01:00
|
|
|
|
|
2022-09-19 15:16:37 +02:00
|
|
|
|
if ((products is null) || (!products.Any()))
|
2022-03-05 16:45:55 +01:00
|
|
|
|
{
|
|
|
|
|
|
WriteLine("No products found to delete.");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2022-09-19 15:16:37 +02:00
|
|
|
|
if (db.Products is null) return 0;
|
2022-03-05 16:45:55 +01:00
|
|
|
|
db.Products.RemoveRange(products);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int affected = db.SaveChanges();
|
|
|
|
|
|
t.Commit();
|
|
|
|
|
|
return affected;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-09-19 15:16:37 +02:00
|
|
|
|
|
|
|
|
|
|
static (int affected, int[]? productIds) IncreaseProductPricesBetter(
|
|
|
|
|
|
string productNameStartsWith, decimal amount)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (db.Products is null) return (0, null);
|
|
|
|
|
|
|
|
|
|
|
|
// Get products whose name starts with name.
|
|
|
|
|
|
IQueryable<Product>? products = db.Products.Where(
|
|
|
|
|
|
p => p.ProductName.StartsWith(productNameStartsWith));
|
|
|
|
|
|
|
|
|
|
|
|
int affected = products.ExecuteUpdate(s => s.SetProperty(
|
|
|
|
|
|
p => p.Cost, // Property selector lambda expression.
|
|
|
|
|
|
p => p.Cost + amount)); // Value to update to lambda expression.
|
|
|
|
|
|
|
|
|
|
|
|
int[] productIds = products.Select(p => p.ProductId).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
return (affected, productIds);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int DeleteProductsBetter(string productNameStartsWith)
|
|
|
|
|
|
{
|
|
|
|
|
|
using (Northwind db = new())
|
|
|
|
|
|
{
|
|
|
|
|
|
int affected = 0;
|
|
|
|
|
|
|
|
|
|
|
|
IQueryable<Product>? products = db.Products?.Where(
|
|
|
|
|
|
p => p.ProductName.StartsWith(productNameStartsWith));
|
|
|
|
|
|
|
|
|
|
|
|
if ((products is null) || (!products.Any()))
|
|
|
|
|
|
{
|
|
|
|
|
|
WriteLine("No products found to delete.");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
affected = products.ExecuteDelete();
|
|
|
|
|
|
}
|
|
|
|
|
|
return affected;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-03-05 16:45:55 +01:00
|
|
|
|
}
|