Initial commit: ADO.NET Lab Application
This commit is contained in:
commit
551f5e3977
3
AdoNetShop.slnx
Normal file
3
AdoNetShop.slnx
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<Solution>
|
||||
<Project Path="AdoNetShop/AdoNetShop.csproj" />
|
||||
</Solution>
|
||||
23
AdoNetShop/AdoNetShop.csproj
Normal file
23
AdoNetShop/AdoNetShop.csproj
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
38
AdoNetShop/Data/CategoryRepository.cs
Normal file
38
AdoNetShop/Data/CategoryRepository.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System.Data;
|
||||
using AdoNetShop.Models;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace AdoNetShop.Data;
|
||||
|
||||
public class CategoryRepository
|
||||
{
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
|
||||
public CategoryRepository(DbConnectionFactory connectionFactory)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public async Task<List<Category>> GetAllAsync()
|
||||
{
|
||||
var categories = new List<Category>();
|
||||
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "SELECT Id, Name FROM Categories";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
categories.Add(new Category
|
||||
{
|
||||
Id = reader.GetInt32(0),
|
||||
Name = reader.GetString(1)
|
||||
});
|
||||
}
|
||||
|
||||
return categories;
|
||||
}
|
||||
}
|
||||
40
AdoNetShop/Data/CustomerRepository.cs
Normal file
40
AdoNetShop/Data/CustomerRepository.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System.Data;
|
||||
using AdoNetShop.Models;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace AdoNetShop.Data;
|
||||
|
||||
public class CustomerRepository
|
||||
{
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
|
||||
public CustomerRepository(DbConnectionFactory connectionFactory)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
public async Task<List<Customer>> GetAllAsync()
|
||||
{
|
||||
var customers = new List<Customer>();
|
||||
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "SELECT Id, Name, Email, Phone FROM Customers";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
customers.Add(new Customer
|
||||
{
|
||||
Id = reader.GetInt32(0),
|
||||
Name = reader.GetString(1),
|
||||
Email = reader.GetString(2),
|
||||
Phone = reader.IsDBNull(3) ? null : reader.GetString(3)
|
||||
});
|
||||
}
|
||||
|
||||
return customers;
|
||||
}
|
||||
}
|
||||
22
AdoNetShop/Data/DbConnectionFactory.cs
Normal file
22
AdoNetShop/Data/DbConnectionFactory.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace AdoNetShop.Data;
|
||||
|
||||
public class DbConnectionFactory
|
||||
{
|
||||
private readonly string _connectionString;
|
||||
|
||||
public DbConnectionFactory(IConfiguration configuration)
|
||||
{
|
||||
// Получаем строку подключения из конфигурации (appsettings.json)
|
||||
_connectionString = configuration.GetConnectionString("DefaultConnection")
|
||||
?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
|
||||
}
|
||||
|
||||
// Фабричный метод для создания и настройки подключения
|
||||
public SqlConnection CreateConnection()
|
||||
{
|
||||
return new SqlConnection(_connectionString);
|
||||
}
|
||||
}
|
||||
117
AdoNetShop/Data/OrderRepository.cs
Normal file
117
AdoNetShop/Data/OrderRepository.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
using System.Data;
|
||||
using AdoNetShop.Models;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace AdoNetShop.Data;
|
||||
|
||||
public class OrderRepository
|
||||
{
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
|
||||
public OrderRepository(DbConnectionFactory connectionFactory)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
// Демонстрация транзакции (Создание заказа)
|
||||
public async Task<int> CreateOrderWithTransactionAsync(Order order)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
// 1. Начинаем транзакцию
|
||||
await using var transaction = (SqlTransaction)await connection.BeginTransactionAsync();
|
||||
|
||||
try
|
||||
{
|
||||
// 2. Создаем сам заказ
|
||||
string insertOrderQuery = @"
|
||||
INSERT INTO Orders (CustomerId, OrderDate, Status, TotalAmount)
|
||||
VALUES (@CustomerId, @OrderDate, @Status, @TotalAmount);
|
||||
SELECT SCOPE_IDENTITY();";
|
||||
|
||||
await using var insertOrderCommand = new SqlCommand(insertOrderQuery, connection, transaction);
|
||||
insertOrderCommand.Parameters.Add("@CustomerId", SqlDbType.Int).Value = order.CustomerId;
|
||||
insertOrderCommand.Parameters.Add("@OrderDate", SqlDbType.DateTime2).Value = order.OrderDate;
|
||||
insertOrderCommand.Parameters.Add("@Status", SqlDbType.NVarChar, 50).Value = order.Status;
|
||||
insertOrderCommand.Parameters.Add("@TotalAmount", SqlDbType.Decimal).Value = order.TotalAmount;
|
||||
|
||||
var newOrderIdObj = await insertOrderCommand.ExecuteScalarAsync();
|
||||
if (newOrderIdObj == null) throw new Exception("Failed to create order.");
|
||||
int newOrderId = Convert.ToInt32(newOrderIdObj);
|
||||
|
||||
// 3. Добавляем товары заказа и обновляем остатки
|
||||
string insertItemQuery = @"
|
||||
INSERT INTO OrderItems (OrderId, ProductId, Quantity, Price)
|
||||
VALUES (@OrderId, @ProductId, @Quantity, @Price)";
|
||||
|
||||
string updateStockQuery = @"
|
||||
UPDATE Products
|
||||
SET StockQuantity = StockQuantity - @Quantity
|
||||
WHERE Id = @ProductId AND StockQuantity >= @Quantity";
|
||||
|
||||
foreach (var item in order.Items)
|
||||
{
|
||||
// Проверка наличия и уменьшение остатка
|
||||
await using var updateStockCommand = new SqlCommand(updateStockQuery, connection, transaction);
|
||||
updateStockCommand.Parameters.Add("@ProductId", SqlDbType.Int).Value = item.ProductId;
|
||||
updateStockCommand.Parameters.Add("@Quantity", SqlDbType.Int).Value = item.Quantity;
|
||||
|
||||
int rowsAffected = await updateStockCommand.ExecuteNonQueryAsync();
|
||||
if (rowsAffected == 0)
|
||||
{
|
||||
// Если обновление не удалось (недостаточно товара или неверный ID),
|
||||
// генерируем исключение. Это приведет к переходу в блок catch и откату транзакции.
|
||||
throw new Exception($"Недостаточно товара на складе для ProductId: {item.ProductId}");
|
||||
}
|
||||
|
||||
// Добавление позиции заказа
|
||||
await using var insertItemCommand = new SqlCommand(insertItemQuery, connection, transaction);
|
||||
insertItemCommand.Parameters.Add("@OrderId", SqlDbType.Int).Value = newOrderId;
|
||||
insertItemCommand.Parameters.Add("@ProductId", SqlDbType.Int).Value = item.ProductId;
|
||||
insertItemCommand.Parameters.Add("@Quantity", SqlDbType.Int).Value = item.Quantity;
|
||||
insertItemCommand.Parameters.Add("@Price", SqlDbType.Decimal).Value = item.Price;
|
||||
|
||||
await insertItemCommand.ExecuteNonQueryAsync();
|
||||
}
|
||||
|
||||
// 4. Если всё прошло успешно, фиксируем транзакцию
|
||||
await transaction.CommitAsync();
|
||||
return newOrderId;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 5. При возникновении любой ошибки откатываем транзакцию
|
||||
// Все изменения (созданный заказ, измененные остатки) будут отменены
|
||||
await transaction.RollbackAsync();
|
||||
|
||||
// Пробрасываем ошибку дальше для обработки на уровне UI/Сервиса
|
||||
throw new Exception($"Ошибка при создании заказа. Транзакция отменена. Детали: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Получение списка заказов (простая реализация)
|
||||
public async Task<List<Order>> GetAllOrdersBasicAsync()
|
||||
{
|
||||
var orders = new List<Order>();
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "SELECT Id, CustomerId, OrderDate, Status, TotalAmount FROM Orders";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
orders.Add(new Order
|
||||
{
|
||||
Id = reader.GetInt32(0),
|
||||
CustomerId = reader.GetInt32(1),
|
||||
OrderDate = reader.GetDateTime(2),
|
||||
Status = reader.GetString(3),
|
||||
TotalAmount = reader.GetDecimal(4)
|
||||
});
|
||||
}
|
||||
return orders;
|
||||
}
|
||||
}
|
||||
163
AdoNetShop/Data/ProductRepository.cs
Normal file
163
AdoNetShop/Data/ProductRepository.cs
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
using System.Data;
|
||||
using AdoNetShop.Models;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace AdoNetShop.Data;
|
||||
|
||||
public class ProductRepository
|
||||
{
|
||||
private readonly DbConnectionFactory _connectionFactory;
|
||||
|
||||
public ProductRepository(DbConnectionFactory connectionFactory)
|
||||
{
|
||||
_connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
// CRUD: Read All (Получение списка)
|
||||
public async Task<List<Product>> GetAllAsync()
|
||||
{
|
||||
var products = new List<Product>();
|
||||
|
||||
// Используем await using для автоматического освобождения ресурсов
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync(); // Открываем подключение
|
||||
|
||||
string query = "SELECT Id, Name, Description, Price, StockQuantity, CategoryId FROM Products";
|
||||
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
|
||||
// SqlDataReader обеспечивает потоковое чтение результатов (forward-only)
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
while (await reader.ReadAsync())
|
||||
{
|
||||
products.Add(new Product
|
||||
{
|
||||
Id = reader.GetInt32(reader.GetOrdinal("Id")),
|
||||
Name = reader.GetString(reader.GetOrdinal("Name")),
|
||||
// Обработка возможного NULL значения для Description
|
||||
Description = reader.IsDBNull(reader.GetOrdinal("Description")) ? null : reader.GetString(reader.GetOrdinal("Description")),
|
||||
Price = reader.GetDecimal(reader.GetOrdinal("Price")),
|
||||
StockQuantity = reader.GetInt32(reader.GetOrdinal("StockQuantity")),
|
||||
CategoryId = reader.GetInt32(reader.GetOrdinal("CategoryId"))
|
||||
});
|
||||
}
|
||||
|
||||
return products;
|
||||
}
|
||||
|
||||
// CRUD: Read One (Получение одного товара по ID)
|
||||
public async Task<Product?> GetByIdAsync(int id)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
// Использование параметров для предотвращения SQL Injections
|
||||
string query = "SELECT Id, Name, Description, Price, StockQuantity, CategoryId FROM Products WHERE Id = @Id";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
|
||||
await using var reader = await command.ExecuteReaderAsync();
|
||||
|
||||
if (await reader.ReadAsync())
|
||||
{
|
||||
return new Product
|
||||
{
|
||||
Id = reader.GetInt32(reader.GetOrdinal("Id")),
|
||||
Name = reader.GetString(reader.GetOrdinal("Name")),
|
||||
Description = reader.IsDBNull(reader.GetOrdinal("Description")) ? null : reader.GetString(reader.GetOrdinal("Description")),
|
||||
Price = reader.GetDecimal(reader.GetOrdinal("Price")),
|
||||
StockQuantity = reader.GetInt32(reader.GetOrdinal("StockQuantity")),
|
||||
CategoryId = reader.GetInt32(reader.GetOrdinal("CategoryId"))
|
||||
};
|
||||
}
|
||||
|
||||
return null; // Если товар не найден
|
||||
}
|
||||
|
||||
// CRUD: Create (Добавление)
|
||||
public async Task<int> CreateAsync(Product product)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
// Используем OUTPUT INSERTED.Id или SCOPE_IDENTITY() для получения сгенерированного Id
|
||||
string query = @"
|
||||
INSERT INTO Products (Name, Description, Price, StockQuantity, CategoryId)
|
||||
VALUES (@Name, @Description, @Price, @StockQuantity, @CategoryId);
|
||||
SELECT SCOPE_IDENTITY();";
|
||||
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
|
||||
// Явное указание типов параметров (хорошая практика)
|
||||
command.Parameters.Add("@Name", SqlDbType.NVarChar, 200).Value = product.Name;
|
||||
command.Parameters.Add("@Description", SqlDbType.NVarChar, -1).Value = (object?)product.Description ?? DBNull.Value;
|
||||
command.Parameters.Add("@Price", SqlDbType.Decimal).Value = product.Price;
|
||||
command.Parameters.Add("@StockQuantity", SqlDbType.Int).Value = product.StockQuantity;
|
||||
command.Parameters.Add("@CategoryId", SqlDbType.Int).Value = product.CategoryId;
|
||||
|
||||
// ExecuteScalarAsync используется для получения единственного значения (в данном случае Id)
|
||||
var newId = await command.ExecuteScalarAsync();
|
||||
return Convert.ToInt32(newId);
|
||||
}
|
||||
|
||||
// CRUD: Update (Обновление)
|
||||
public async Task<bool> UpdateAsync(Product product)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = @"
|
||||
UPDATE Products
|
||||
SET Name = @Name, Description = @Description, Price = @Price,
|
||||
StockQuantity = @StockQuantity, CategoryId = @CategoryId
|
||||
WHERE Id = @Id";
|
||||
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = product.Id;
|
||||
command.Parameters.Add("@Name", SqlDbType.NVarChar, 200).Value = product.Name;
|
||||
command.Parameters.Add("@Description", SqlDbType.NVarChar, -1).Value = (object?)product.Description ?? DBNull.Value;
|
||||
command.Parameters.Add("@Price", SqlDbType.Decimal).Value = product.Price;
|
||||
command.Parameters.Add("@StockQuantity", SqlDbType.Int).Value = product.StockQuantity;
|
||||
command.Parameters.Add("@CategoryId", SqlDbType.Int).Value = product.CategoryId;
|
||||
|
||||
// ExecuteNonQueryAsync используется для запросов INSERT/UPDATE/DELETE
|
||||
int rowsAffected = await command.ExecuteNonQueryAsync();
|
||||
return rowsAffected > 0;
|
||||
}
|
||||
|
||||
// CRUD: Delete (Удаление)
|
||||
public async Task<bool> DeleteAsync(int id)
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
await connection.OpenAsync();
|
||||
|
||||
string query = "DELETE FROM Products WHERE Id = @Id";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
command.Parameters.Add("@Id", SqlDbType.Int).Value = id;
|
||||
|
||||
int rowsAffected = await command.ExecuteNonQueryAsync();
|
||||
return rowsAffected > 0;
|
||||
}
|
||||
|
||||
// Демонстрация DataAdapter и автономной модели (Disconnected Mode)
|
||||
public async Task<DataTable> GetProductsTableAsync()
|
||||
{
|
||||
await using var connection = _connectionFactory.CreateConnection();
|
||||
|
||||
string query = "SELECT Id, Name, Price, StockQuantity FROM Products";
|
||||
await using var command = new SqlCommand(query, connection);
|
||||
|
||||
// SqlDataAdapter служит мостом между БД и DataSet/DataTable
|
||||
using var adapter = new SqlDataAdapter(command);
|
||||
var table = new DataTable("Products");
|
||||
|
||||
// Метод Fill открывает подключение (если оно закрыто), выполняет запрос,
|
||||
// заполняет DataTable и закрывает подключение (если оно было закрыто).
|
||||
// Это и есть автономный режим.
|
||||
await Task.Run(() => adapter.Fill(table));
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
7
AdoNetShop/Models/Category.cs
Normal file
7
AdoNetShop/Models/Category.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace AdoNetShop.Models;
|
||||
|
||||
public class Category
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
9
AdoNetShop/Models/Customer.cs
Normal file
9
AdoNetShop/Models/Customer.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
namespace AdoNetShop.Models;
|
||||
|
||||
public class Customer
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string? Phone { get; set; }
|
||||
}
|
||||
12
AdoNetShop/Models/Order.cs
Normal file
12
AdoNetShop/Models/Order.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace AdoNetShop.Models;
|
||||
|
||||
public class Order
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int CustomerId { get; set; }
|
||||
public DateTime OrderDate { get; set; }
|
||||
public string Status { get; set; } = "New";
|
||||
public decimal TotalAmount { get; set; }
|
||||
|
||||
public List<OrderItem> Items { get; set; } = new List<OrderItem>();
|
||||
}
|
||||
10
AdoNetShop/Models/OrderItem.cs
Normal file
10
AdoNetShop/Models/OrderItem.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
namespace AdoNetShop.Models;
|
||||
|
||||
public class OrderItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int OrderId { get; set; }
|
||||
public int ProductId { get; set; }
|
||||
public int Quantity { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
}
|
||||
14
AdoNetShop/Models/Product.cs
Normal file
14
AdoNetShop/Models/Product.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
namespace AdoNetShop.Models;
|
||||
|
||||
public class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public decimal Price { get; set; }
|
||||
public int StockQuantity { get; set; }
|
||||
public int CategoryId { get; set; }
|
||||
|
||||
// Навигационное свойство (заполняется опционально)
|
||||
public Category? Category { get; set; }
|
||||
}
|
||||
297
AdoNetShop/Program.cs
Normal file
297
AdoNetShop/Program.cs
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
using System.Data;
|
||||
using AdoNetShop.Data;
|
||||
using AdoNetShop.Models;
|
||||
using AdoNetShop.Services;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace AdoNetShop;
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
// 1. Настройка конфигурации для чтения appsettings.json
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
||||
.Build();
|
||||
|
||||
// 2. "Ручной" Dependency Injection
|
||||
var connectionFactory = new DbConnectionFactory(configuration);
|
||||
|
||||
var productRepo = new ProductRepository(connectionFactory);
|
||||
var categoryRepo = new CategoryRepository(connectionFactory);
|
||||
var customerRepo = new CustomerRepository(connectionFactory);
|
||||
var orderRepo = new OrderRepository(connectionFactory);
|
||||
|
||||
var shopService = new ShopService(productRepo, categoryRepo, customerRepo, orderRepo);
|
||||
|
||||
// 3. Главный цикл приложения
|
||||
bool exit = false;
|
||||
while (!exit)
|
||||
{
|
||||
Console.Clear();
|
||||
Console.WriteLine("================================");
|
||||
Console.WriteLine(" ADO.NET SHOP");
|
||||
Console.WriteLine("================================");
|
||||
Console.WriteLine("1. Список товаров");
|
||||
Console.WriteLine("2. Найти товар по ID");
|
||||
Console.WriteLine("3. Добавить товар");
|
||||
Console.WriteLine("4. Изменить товар");
|
||||
Console.WriteLine("5. Удалить товар");
|
||||
Console.WriteLine("6. Список категорий");
|
||||
Console.WriteLine("7. Список клиентов");
|
||||
Console.WriteLine("8. Создать заказ (Демонстрация Transaction)");
|
||||
Console.WriteLine("9. Просмотреть заказы");
|
||||
Console.WriteLine("10. Демонстрация DataAdapter (Disconnected mode)");
|
||||
Console.WriteLine("0. Выход");
|
||||
Console.WriteLine("================================");
|
||||
Console.Write("Выберите действие: ");
|
||||
|
||||
var input = Console.ReadLine();
|
||||
|
||||
try
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case "1":
|
||||
await ShowAllProducts(shopService);
|
||||
break;
|
||||
case "2":
|
||||
await FindProduct(shopService);
|
||||
break;
|
||||
case "3":
|
||||
await AddProduct(shopService);
|
||||
break;
|
||||
case "4":
|
||||
await UpdateProduct(shopService);
|
||||
break;
|
||||
case "5":
|
||||
await DeleteProduct(shopService);
|
||||
break;
|
||||
case "6":
|
||||
await ShowAllCategories(shopService);
|
||||
break;
|
||||
case "7":
|
||||
await ShowAllCustomers(shopService);
|
||||
break;
|
||||
case "8":
|
||||
await CreateOrder(shopService);
|
||||
break;
|
||||
case "9":
|
||||
await ShowAllOrders(shopService);
|
||||
break;
|
||||
case "10":
|
||||
await DemoDataAdapter(shopService);
|
||||
break;
|
||||
case "0":
|
||||
exit = true;
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine("Неверный ввод.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine($"\n[ОШИБКА]: {ex.Message}");
|
||||
if(ex.InnerException != null)
|
||||
{
|
||||
Console.WriteLine($"[ДЕТАЛИ]: {ex.InnerException.Message}");
|
||||
}
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
if (!exit)
|
||||
{
|
||||
Console.WriteLine("\nНажмите любую клавишу для продолжения...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ShowAllProducts(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Список товаров ---");
|
||||
var products = await service.GetAllProductsAsync();
|
||||
foreach (var p in products)
|
||||
{
|
||||
Console.WriteLine($"[{p.Id}] {p.Name} | Цена: {p.Price:C} | Остаток: {p.StockQuantity} | Кат: {p.CategoryId}");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task FindProduct(ShopService service)
|
||||
{
|
||||
Console.Write("\nВведите ID товара: ");
|
||||
if (int.TryParse(Console.ReadLine(), out int id))
|
||||
{
|
||||
var product = await service.GetProductByIdAsync(id);
|
||||
if (product != null)
|
||||
{
|
||||
Console.WriteLine($"Найдено: [{product.Id}] {product.Name} - {product.Description} | {product.Price:C} | {product.StockQuantity} шт.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Товар не найден.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Некорректный ID.");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task AddProduct(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Добавление товара ---");
|
||||
|
||||
Console.Write("Название: ");
|
||||
string name = Console.ReadLine() ?? "";
|
||||
|
||||
Console.Write("Описание: ");
|
||||
string desc = Console.ReadLine() ?? "";
|
||||
|
||||
Console.Write("Цена: ");
|
||||
if (!decimal.TryParse(Console.ReadLine(), out decimal price)) throw new ArgumentException("Неверный формат цены.");
|
||||
|
||||
Console.Write("Количество: ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int quantity)) throw new ArgumentException("Неверный формат количества.");
|
||||
|
||||
Console.Write("ID Категории: ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int catId)) throw new ArgumentException("Неверный формат ID категории.");
|
||||
|
||||
var product = new Product
|
||||
{
|
||||
Name = name,
|
||||
Description = desc,
|
||||
Price = price,
|
||||
StockQuantity = quantity,
|
||||
CategoryId = catId
|
||||
};
|
||||
|
||||
int newId = await service.CreateProductAsync(product);
|
||||
Console.WriteLine($"Товар успешно добавлен. Новый ID: {newId}");
|
||||
}
|
||||
|
||||
private static async Task UpdateProduct(ShopService service)
|
||||
{
|
||||
Console.Write("\nВведите ID товара для обновления: ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int id)) return;
|
||||
|
||||
var product = await service.GetProductByIdAsync(id);
|
||||
if (product == null)
|
||||
{
|
||||
Console.WriteLine("Товар не найден.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Текущее название: {product.Name}");
|
||||
Console.Write("Новое название (оставьте пустым, чтобы не менять): ");
|
||||
string name = Console.ReadLine() ?? "";
|
||||
if (!string.IsNullOrWhiteSpace(name)) product.Name = name;
|
||||
|
||||
Console.WriteLine($"Текущая цена: {product.Price}");
|
||||
Console.Write("Новая цена (оставьте пустым, чтобы не менять): ");
|
||||
string priceStr = Console.ReadLine() ?? "";
|
||||
if (!string.IsNullOrWhiteSpace(priceStr) && decimal.TryParse(priceStr, out decimal price)) product.Price = price;
|
||||
|
||||
bool updated = await service.UpdateProductAsync(product);
|
||||
Console.WriteLine(updated ? "Товар обновлен." : "Не удалось обновить товар.");
|
||||
}
|
||||
|
||||
private static async Task DeleteProduct(ShopService service)
|
||||
{
|
||||
Console.Write("\nВведите ID товара для удаления: ");
|
||||
if (int.TryParse(Console.ReadLine(), out int id))
|
||||
{
|
||||
bool deleted = await service.DeleteProductAsync(id);
|
||||
Console.WriteLine(deleted ? "Товар удален." : "Товар не найден или не может быть удален.");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task ShowAllCategories(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Категории ---");
|
||||
var cats = await service.GetAllCategoriesAsync();
|
||||
foreach (var c in cats) Console.WriteLine($"[{c.Id}] {c.Name}");
|
||||
}
|
||||
|
||||
private static async Task ShowAllCustomers(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Клиенты ---");
|
||||
var customers = await service.GetAllCustomersAsync();
|
||||
foreach (var c in customers) Console.WriteLine($"[{c.Id}] {c.Name} ({c.Email})");
|
||||
}
|
||||
|
||||
private static async Task CreateOrder(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Создание заказа ---");
|
||||
|
||||
await ShowAllCustomers(service);
|
||||
Console.Write("Введите ID клиента: ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int customerId)) return;
|
||||
|
||||
var items = new List<(int ProductId, int Quantity)>();
|
||||
|
||||
while (true)
|
||||
{
|
||||
Console.Write("Введите ID товара (или 0 для завершения): ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int productId)) continue;
|
||||
if (productId == 0) break;
|
||||
|
||||
Console.Write("Введите количество: ");
|
||||
if (!int.TryParse(Console.ReadLine(), out int quantity) || quantity <= 0)
|
||||
{
|
||||
Console.WriteLine("Неверное количество.");
|
||||
continue;
|
||||
}
|
||||
|
||||
items.Add((productId, quantity));
|
||||
}
|
||||
|
||||
if (items.Count == 0)
|
||||
{
|
||||
Console.WriteLine("Заказ отменен (нет товаров).");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("Попытка создать заказ в БД (Транзакция)...");
|
||||
int orderId = await service.CreateOrderAsync(customerId, items);
|
||||
Console.WriteLine($"Заказ успешно создан! ID: {orderId}");
|
||||
}
|
||||
|
||||
private static async Task ShowAllOrders(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Заказы ---");
|
||||
var orders = await service.GetAllOrdersAsync();
|
||||
foreach (var o in orders)
|
||||
{
|
||||
Console.WriteLine($"[{o.Id}] Клиент: {o.CustomerId} | Сумма: {o.TotalAmount:C} | Дата: {o.OrderDate:g} | Статус: {o.Status}");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task DemoDataAdapter(ShopService service)
|
||||
{
|
||||
Console.WriteLine("\n--- Демонстрация DataAdapter (Disconnected mode) ---");
|
||||
Console.WriteLine("Запрашиваем данные через DataAdapter.Fill()...");
|
||||
|
||||
DataTable table = await service.GetProductsTableAsync();
|
||||
|
||||
Console.WriteLine($"Получено строк: {table.Rows.Count}");
|
||||
Console.WriteLine("Подключение к БД уже закрыто. Данные находятся в памяти (DataTable).\n");
|
||||
|
||||
Console.WriteLine("Id\tName\t\t\tPrice");
|
||||
Console.WriteLine("--------------------------------------------------");
|
||||
|
||||
// Чтение данных из автономного DataTable
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
int id = (int)row["Id"];
|
||||
string name = (string)row["Name"];
|
||||
decimal price = (decimal)row["Price"];
|
||||
|
||||
Console.WriteLine($"{id}\t{name,-20}\t{price:C}");
|
||||
}
|
||||
}
|
||||
}
|
||||
92
AdoNetShop/Services/ShopService.cs
Normal file
92
AdoNetShop/Services/ShopService.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
using AdoNetShop.Data;
|
||||
using AdoNetShop.Models;
|
||||
|
||||
namespace AdoNetShop.Services;
|
||||
|
||||
// Сервисы могут содержать дополнительную бизнес-логику,
|
||||
// но в рамках этой лабы они выступают простыми прокси к репозиториям.
|
||||
public class ShopService
|
||||
{
|
||||
private readonly ProductRepository _productRepository;
|
||||
private readonly CategoryRepository _categoryRepository;
|
||||
private readonly CustomerRepository _customerRepository;
|
||||
private readonly OrderRepository _orderRepository;
|
||||
|
||||
public ShopService(
|
||||
ProductRepository productRepository,
|
||||
CategoryRepository categoryRepository,
|
||||
CustomerRepository customerRepository,
|
||||
OrderRepository orderRepository)
|
||||
{
|
||||
_productRepository = productRepository;
|
||||
_categoryRepository = categoryRepository;
|
||||
_customerRepository = customerRepository;
|
||||
_orderRepository = orderRepository;
|
||||
}
|
||||
|
||||
public Task<List<Product>> GetAllProductsAsync() => _productRepository.GetAllAsync();
|
||||
public Task<Product?> GetProductByIdAsync(int id) => _productRepository.GetByIdAsync(id);
|
||||
|
||||
public async Task<int> CreateProductAsync(Product product)
|
||||
{
|
||||
// Пример простой валидации на уровне сервиса
|
||||
if (product.Price <= 0) throw new ArgumentException("Price must be greater than 0");
|
||||
if (product.StockQuantity < 0) throw new ArgumentException("Stock cannot be negative");
|
||||
|
||||
return await _productRepository.CreateAsync(product);
|
||||
}
|
||||
|
||||
public Task<bool> UpdateProductAsync(Product product) => _productRepository.UpdateAsync(product);
|
||||
public Task<bool> DeleteProductAsync(int id) => _productRepository.DeleteAsync(id);
|
||||
|
||||
public Task<List<Category>> GetAllCategoriesAsync() => _categoryRepository.GetAllAsync();
|
||||
public Task<List<Customer>> GetAllCustomersAsync() => _customerRepository.GetAllAsync();
|
||||
|
||||
public async Task<int> CreateOrderAsync(int customerId, List<(int ProductId, int Quantity)> requestedItems)
|
||||
{
|
||||
// 1. Формируем заказ
|
||||
var order = new Order
|
||||
{
|
||||
CustomerId = customerId,
|
||||
OrderDate = DateTime.Now,
|
||||
Status = "Created",
|
||||
Items = new List<OrderItem>()
|
||||
};
|
||||
|
||||
decimal totalAmount = 0;
|
||||
|
||||
// 2. Получаем актуальные цены товаров
|
||||
foreach (var reqItem in requestedItems)
|
||||
{
|
||||
var product = await _productRepository.GetByIdAsync(reqItem.ProductId);
|
||||
if (product == null)
|
||||
{
|
||||
throw new ArgumentException($"Product with ID {reqItem.ProductId} not found.");
|
||||
}
|
||||
|
||||
if(product.StockQuantity < reqItem.Quantity)
|
||||
{
|
||||
throw new ArgumentException($"Not enough stock for product '{product.Name}'. Available: {product.StockQuantity}, Requested: {reqItem.Quantity}");
|
||||
}
|
||||
|
||||
var orderItem = new OrderItem
|
||||
{
|
||||
ProductId = reqItem.ProductId,
|
||||
Quantity = reqItem.Quantity,
|
||||
Price = product.Price
|
||||
};
|
||||
|
||||
order.Items.Add(orderItem);
|
||||
totalAmount += (reqItem.Quantity * product.Price);
|
||||
}
|
||||
|
||||
order.TotalAmount = totalAmount;
|
||||
|
||||
// 3. Вызываем репозиторий для сохранения (внутри будет транзакция)
|
||||
return await _orderRepository.CreateOrderWithTransactionAsync(order);
|
||||
}
|
||||
|
||||
public Task<List<Order>> GetAllOrdersAsync() => _orderRepository.GetAllOrdersBasicAsync();
|
||||
|
||||
public Task<System.Data.DataTable> GetProductsTableAsync() => _productRepository.GetProductsTableAsync();
|
||||
}
|
||||
5
AdoNetShop/appsettings.json
Normal file
5
AdoNetShop/appsettings.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=localhost;Database=AdoNetShop;Trusted_Connection=True;TrustServerCertificate=True;"
|
||||
}
|
||||
}
|
||||
634
AdoNetShop/bin/Debug/net8.0/AdoNetShop.deps.json
Normal file
634
AdoNetShop/bin/Debug/net8.0/AdoNetShop.deps.json
Normal file
|
|
@ -0,0 +1,634 @@
|
|||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v8.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v8.0": {
|
||||
"AdoNetShop/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Data.SqlClient": "5.2.0",
|
||||
"Microsoft.Extensions.Configuration": "8.0.0",
|
||||
"Microsoft.Extensions.Configuration.Binder": "8.0.1",
|
||||
"Microsoft.Extensions.Configuration.Json": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"AdoNetShop.dll": {}
|
||||
}
|
||||
},
|
||||
"Azure.Core/1.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Bcl.AsyncInterfaces": "1.1.1",
|
||||
"System.Memory.Data": "1.0.2"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Azure.Core.dll": {
|
||||
"assemblyVersion": "1.35.0.0",
|
||||
"fileVersion": "1.3500.23.45706"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Azure.Identity/1.10.3": {
|
||||
"dependencies": {
|
||||
"Azure.Core": "1.35.0",
|
||||
"Microsoft.Identity.Client": "4.56.0",
|
||||
"Microsoft.Identity.Client.Extensions.Msal": "4.56.0",
|
||||
"System.Security.Cryptography.ProtectedData": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Azure.Identity.dll": {
|
||||
"assemblyVersion": "1.10.3.0",
|
||||
"fileVersion": "1.1000.323.51804"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces/1.1.1": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/Microsoft.Bcl.AsyncInterfaces.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "4.700.20.21406"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.SqlClient/5.2.0": {
|
||||
"dependencies": {
|
||||
"Azure.Identity": "1.10.3",
|
||||
"Microsoft.Data.SqlClient.SNI.runtime": "5.2.0",
|
||||
"Microsoft.Identity.Client": "4.56.0",
|
||||
"Microsoft.IdentityModel.JsonWebTokens": "6.35.0",
|
||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0",
|
||||
"Microsoft.SqlServer.Server": "1.0.0",
|
||||
"System.Configuration.ConfigurationManager": "8.0.0",
|
||||
"System.Runtime.Caching": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Data.SqlClient.dll": {
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.20.24059.2"
|
||||
}
|
||||
},
|
||||
"resources": {
|
||||
"lib/net8.0/de/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "de"
|
||||
},
|
||||
"lib/net8.0/es/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "es"
|
||||
},
|
||||
"lib/net8.0/fr/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "fr"
|
||||
},
|
||||
"lib/net8.0/it/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "it"
|
||||
},
|
||||
"lib/net8.0/ja/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "ja"
|
||||
},
|
||||
"lib/net8.0/ko/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "ko"
|
||||
},
|
||||
"lib/net8.0/pt-BR/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "pt-BR"
|
||||
},
|
||||
"lib/net8.0/ru/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "ru"
|
||||
},
|
||||
"lib/net8.0/zh-Hans/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "zh-Hans"
|
||||
},
|
||||
"lib/net8.0/zh-Hant/Microsoft.Data.SqlClient.resources.dll": {
|
||||
"locale": "zh-Hant"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/unix/lib/net8.0/Microsoft.Data.SqlClient.dll": {
|
||||
"rid": "unix",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.20.24059.2"
|
||||
},
|
||||
"runtimes/win/lib/net8.0/Microsoft.Data.SqlClient.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "5.0.0.0",
|
||||
"fileVersion": "5.20.24059.2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Data.SqlClient.SNI.runtime/5.2.0": {
|
||||
"runtimeTargets": {
|
||||
"runtimes/win-arm/native/Microsoft.Data.SqlClient.SNI.dll": {
|
||||
"rid": "win-arm",
|
||||
"assetType": "native",
|
||||
"fileVersion": "5.2.0.0"
|
||||
},
|
||||
"runtimes/win-arm64/native/Microsoft.Data.SqlClient.SNI.dll": {
|
||||
"rid": "win-arm64",
|
||||
"assetType": "native",
|
||||
"fileVersion": "5.2.0.0"
|
||||
},
|
||||
"runtimes/win-x64/native/Microsoft.Data.SqlClient.SNI.dll": {
|
||||
"rid": "win-x64",
|
||||
"assetType": "native",
|
||||
"fileVersion": "5.2.0.0"
|
||||
},
|
||||
"runtimes/win-x86/native/Microsoft.Data.SqlClient.SNI.dll": {
|
||||
"rid": "win-x86",
|
||||
"assetType": "native",
|
||||
"fileVersion": "5.2.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Configuration.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/8.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Configuration.Binder.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.123.58001"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.FileExtensions/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "8.0.0",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Physical": "8.0.0",
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Configuration.FileExtensions.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Json/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration": "8.0.0",
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Configuration.FileExtensions": "8.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Configuration.Json.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.FileProviders.Abstractions.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Physical/8.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.FileSystemGlobbing": "8.0.0",
|
||||
"Microsoft.Extensions.Primitives": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.FileProviders.Physical.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileSystemGlobbing/8.0.0": {
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.FileSystemGlobbing.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/8.0.0": {
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.Extensions.Primitives.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Identity.Client/4.56.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Abstractions": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.Identity.Client.dll": {
|
||||
"assemblyVersion": "4.56.0.0",
|
||||
"fileVersion": "4.56.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Identity.Client.Extensions.Msal/4.56.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Identity.Client": "4.56.0",
|
||||
"System.Security.Cryptography.ProtectedData": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.Identity.Client.Extensions.Msal.dll": {
|
||||
"assemblyVersion": "4.56.0.0",
|
||||
"fileVersion": "4.56.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/6.35.0": {
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Abstractions.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Tokens": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Abstractions": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Logging.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Protocols/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Logging": "6.35.0",
|
||||
"Microsoft.IdentityModel.Tokens": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Protocols.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Protocols": "6.35.0",
|
||||
"System.IdentityModel.Tokens.Jwt": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Protocols.OpenIdConnect.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Logging": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Tokens.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.SqlServer.Server/1.0.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/Microsoft.SqlServer.Server.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/8.0.0": {
|
||||
"dependencies": {
|
||||
"System.Diagnostics.EventLog": "8.0.0",
|
||||
"System.Security.Cryptography.ProtectedData": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/System.Configuration.ConfigurationManager.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.EventLog/8.0.0": {
|
||||
"runtime": {
|
||||
"lib/net8.0/System.Diagnostics.EventLog.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net8.0/System.Diagnostics.EventLog.Messages.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "0.0.0.0"
|
||||
},
|
||||
"runtimes/win/lib/net8.0/System.Diagnostics.EventLog.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/6.35.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.JsonWebTokens": "6.35.0",
|
||||
"Microsoft.IdentityModel.Tokens": "6.35.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.IdentityModel.Tokens.Jwt.dll": {
|
||||
"assemblyVersion": "6.35.0.0",
|
||||
"fileVersion": "6.35.0.41201"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Memory.Data/1.0.2": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/System.Memory.Data.dll": {
|
||||
"assemblyVersion": "1.0.2.0",
|
||||
"fileVersion": "1.0.221.20802"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Runtime.Caching/8.0.0": {
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "8.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/System.Runtime.Caching.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net8.0/System.Runtime.Caching.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/8.0.0": {
|
||||
"runtime": {
|
||||
"lib/net8.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"assemblyVersion": "8.0.0.0",
|
||||
"fileVersion": "8.0.23.53103"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"AdoNetShop/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Azure.Core/1.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-hENcx03Jyuqv05F4RBEPbxz29UrM3Nbhnr6Wl6NQpoU9BCIbL3XLentrxDCTrH54NLS11Exxi/o8MYgT/cnKFA==",
|
||||
"path": "azure.core/1.35.0",
|
||||
"hashPath": "azure.core.1.35.0.nupkg.sha512"
|
||||
},
|
||||
"Azure.Identity/1.10.3": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==",
|
||||
"path": "azure.identity/1.10.3",
|
||||
"hashPath": "azure.identity.1.10.3.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Bcl.AsyncInterfaces/1.1.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w==",
|
||||
"path": "microsoft.bcl.asyncinterfaces/1.1.1",
|
||||
"hashPath": "microsoft.bcl.asyncinterfaces.1.1.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Data.SqlClient/5.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==",
|
||||
"path": "microsoft.data.sqlclient/5.2.0",
|
||||
"hashPath": "microsoft.data.sqlclient.5.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Data.SqlClient.SNI.runtime/5.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==",
|
||||
"path": "microsoft.data.sqlclient.sni.runtime/5.2.0",
|
||||
"hashPath": "microsoft.data.sqlclient.sni.runtime.5.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-0J/9YNXTMWSZP2p2+nvl8p71zpSwokZXZuJW+VjdErkegAnFdO1XlqtA62SJtgVYHdKu3uPxJHcMR/r35HwFBA==",
|
||||
"path": "microsoft.extensions.configuration/8.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-3lE/iLSutpgX1CC0NOW70FJoGARRHbyKmG7dc0klnUZ9Dd9hS6N/POPWhKhMLCEuNN5nXEY5agmlFtH562vqhQ==",
|
||||
"path": "microsoft.extensions.configuration.abstractions/8.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/8.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-2UKFJnLiBt7Od6nCnTqP9rTIUNhzmn9Hv1l2FchyKbz8xieB9ULwZTbQZMw+M24Qw3F5dzzH1U9PPleN0LNLOQ==",
|
||||
"path": "microsoft.extensions.configuration.binder/8.0.1",
|
||||
"hashPath": "microsoft.extensions.configuration.binder.8.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.FileExtensions/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-McP+Lz/EKwvtCv48z0YImw+L1gi1gy5rHhNaNIY2CrjloV+XY8gydT8DjMR6zWeL13AFK+DioVpppwAuO1Gi1w==",
|
||||
"path": "microsoft.extensions.configuration.fileextensions/8.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.fileextensions.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Json/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-C2wqUoh9OmRL1akaCcKSTmRU8z0kckfImG7zLNI8uyi47Lp+zd5LWAD17waPQEqCz3ioWOCrFUo+JJuoeZLOBw==",
|
||||
"path": "microsoft.extensions.configuration.json/8.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.json.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ZbaMlhJlpisjuWbvXr4LdAst/1XxH3vZ6A0BsgTphZ2L4PGuxRLz7Jr/S7mkAAnOn78Vu0fKhEgNF5JO3zfjqQ==",
|
||||
"path": "microsoft.extensions.fileproviders.abstractions/8.0.0",
|
||||
"hashPath": "microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Physical/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UboiXxpPUpwulHvIAVE36Knq0VSHaAmfrFkegLyBZeaADuKezJ/AIXYAW8F5GBlGk/VaibN2k/Zn1ca8YAfVdA==",
|
||||
"path": "microsoft.extensions.fileproviders.physical/8.0.0",
|
||||
"hashPath": "microsoft.extensions.fileproviders.physical.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.FileSystemGlobbing/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-OK+670i7esqlQrPjdIKRbsyMCe9g5kSLpRRQGSr4Q58AOYEe/hCnfLZprh7viNisSUUQZmMrbbuDaIrP+V1ebQ==",
|
||||
"path": "microsoft.extensions.filesystemglobbing/8.0.0",
|
||||
"hashPath": "microsoft.extensions.filesystemglobbing.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-bXJEZrW9ny8vjMF1JV253WeLhpEVzFo1lyaZu1vQ4ZxWUlVvknZ/+ftFgVheLubb4eZPSwwxBeqS1JkCOjxd8g==",
|
||||
"path": "microsoft.extensions.primitives/8.0.0",
|
||||
"hashPath": "microsoft.extensions.primitives.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Identity.Client/4.56.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==",
|
||||
"path": "microsoft.identity.client/4.56.0",
|
||||
"hashPath": "microsoft.identity.client.4.56.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Identity.Client.Extensions.Msal/4.56.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==",
|
||||
"path": "microsoft.identity.client.extensions.msal/4.56.0",
|
||||
"hashPath": "microsoft.identity.client.extensions.msal.4.56.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==",
|
||||
"path": "microsoft.identitymodel.abstractions/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.abstractions.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==",
|
||||
"path": "microsoft.identitymodel.jsonwebtokens/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.jsonwebtokens.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==",
|
||||
"path": "microsoft.identitymodel.logging/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.logging.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Protocols/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==",
|
||||
"path": "microsoft.identitymodel.protocols/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.protocols.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Protocols.OpenIdConnect/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==",
|
||||
"path": "microsoft.identitymodel.protocols.openidconnect/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.protocols.openidconnect.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==",
|
||||
"path": "microsoft.identitymodel.tokens/6.35.0",
|
||||
"hashPath": "microsoft.identitymodel.tokens.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.SqlServer.Server/1.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==",
|
||||
"path": "microsoft.sqlserver.server/1.0.0",
|
||||
"hashPath": "microsoft.sqlserver.server.1.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-JlYi9XVvIREURRUlGMr1F6vOFLk7YSY4p1vHo4kX3tQ0AGrjqlRWHDi66ImHhy6qwXBG3BJ6Y1QlYQ+Qz6Xgww==",
|
||||
"path": "system.configuration.configurationmanager/8.0.0",
|
||||
"hashPath": "system.configuration.configurationmanager.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.EventLog/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==",
|
||||
"path": "system.diagnostics.eventlog/8.0.0",
|
||||
"hashPath": "system.diagnostics.eventlog.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/6.35.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==",
|
||||
"path": "system.identitymodel.tokens.jwt/6.35.0",
|
||||
"hashPath": "system.identitymodel.tokens.jwt.6.35.0.nupkg.sha512"
|
||||
},
|
||||
"System.Memory.Data/1.0.2": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==",
|
||||
"path": "system.memory.data/1.0.2",
|
||||
"hashPath": "system.memory.data.1.0.2.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.Caching/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-4TmlmvGp4kzZomm7J2HJn6IIx0UUrQyhBDyb5O1XiunZlQImXW+B8b7W/sTPcXhSf9rp5NR5aDtQllwbB5elOQ==",
|
||||
"path": "system.runtime.caching/8.0.0",
|
||||
"hashPath": "system.runtime.caching.8.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/8.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==",
|
||||
"path": "system.security.cryptography.protecteddata/8.0.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.8.0.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.exe
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.exe
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.pdb
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/AdoNetShop.pdb
Normal file
Binary file not shown.
12
AdoNetShop/bin/Debug/net8.0/AdoNetShop.runtimeconfig.json
Normal file
12
AdoNetShop/bin/Debug/net8.0/AdoNetShop.runtimeconfig.json
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net8.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "8.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
AdoNetShop/bin/Debug/net8.0/Azure.Core.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Azure.Core.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Azure.Identity.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Azure.Identity.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Bcl.AsyncInterfaces.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Bcl.AsyncInterfaces.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Data.SqlClient.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Data.SqlClient.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Extensions.Primitives.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Extensions.Primitives.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Identity.Client.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.Identity.Client.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.IdentityModel.Logging.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.IdentityModel.Logging.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.IdentityModel.Tokens.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.SqlServer.Server.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/Microsoft.SqlServer.Server.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/System.Diagnostics.EventLog.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/System.Diagnostics.EventLog.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/System.IdentityModel.Tokens.Jwt.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/System.IdentityModel.Tokens.Jwt.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/System.Memory.Data.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/System.Memory.Data.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/bin/Debug/net8.0/System.Runtime.Caching.dll
Normal file
BIN
AdoNetShop/bin/Debug/net8.0/System.Runtime.Caching.dll
Normal file
Binary file not shown.
Binary file not shown.
5
AdoNetShop/bin/Debug/net8.0/appsettings.json
Normal file
5
AdoNetShop/bin/Debug/net8.0/appsettings.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=localhost;Database=AdoNetShop;Trusted_Connection=True;TrustServerCertificate=True;"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
112
AdoNetShop/obj/AdoNetShop.csproj.nuget.dgspec.json
Normal file
112
AdoNetShop/obj/AdoNetShop.csproj.nuget.dgspec.json
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\AdoNetShop.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\AdoNetShop.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\AdoNetShop.csproj",
|
||||
"projectName": "AdoNetShop",
|
||||
"projectPath": "C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\AdoNetShop.csproj",
|
||||
"packagesPath": "C:\\Users\\ivaiv\\.nuget\\packages\\",
|
||||
"outputPath": "C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\ivaiv\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.FallbackLocation.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net8.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"C:\\Program Files\\dotnet\\library-packs": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"framework": "net8.0",
|
||||
"targetAlias": "net8.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
},
|
||||
"SdkAnalysisLevel": "10.0.400"
|
||||
},
|
||||
"frameworks": {
|
||||
"net8.0": {
|
||||
"framework": "net8.0",
|
||||
"targetAlias": "net8.0",
|
||||
"dependencies": {
|
||||
"Microsoft.Data.SqlClient": {
|
||||
"target": "Package",
|
||||
"version": "[5.2.0, )"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration": {
|
||||
"target": "Package",
|
||||
"version": "[8.0.0, )"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"target": "Package",
|
||||
"version": "[8.0.1, )"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Json": {
|
||||
"target": "Package",
|
||||
"version": "[8.0.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"downloadDependencies": [
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App.Ref",
|
||||
"version": "[8.0.30, 8.0.30]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Host.win-x64",
|
||||
"version": "[8.0.30, 8.0.30]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.NETCore.App.Ref",
|
||||
"version": "[8.0.30, 8.0.30]"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.WindowsDesktop.App.Ref",
|
||||
"version": "[8.0.30, 8.0.30]"
|
||||
}
|
||||
],
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\10.0.400/PortableRuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
AdoNetShop/obj/AdoNetShop.csproj.nuget.g.props
Normal file
16
AdoNetShop/obj/AdoNetShop.csproj.nuget.g.props
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\ivaiv\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\ivaiv\.nuget\packages\" />
|
||||
<SourceRoot Include="C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
7
AdoNetShop/obj/AdoNetShop.csproj.nuget.g.targets
Normal file
7
AdoNetShop/obj/AdoNetShop.csproj.nuget.g.targets
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\8.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.1\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.configuration.binder\8.0.1\buildTransitive\netstandard2.0\Microsoft.Extensions.Configuration.Binder.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
22
AdoNetShop/obj/Debug/net8.0/AdoNetShop.AssemblyInfo.cs
Normal file
22
AdoNetShop/obj/Debug/net8.0/AdoNetShop.AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("AdoNetShop")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("AdoNetShop")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("AdoNetShop")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
edcaefc3f74c59b79e27cc94850e594ffc6716212f1a49064e94007b5ff80557
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
is_global = true
|
||||
build_property.TargetFramework = net8.0
|
||||
build_property.TargetFrameworkIdentifier = .NETCoreApp
|
||||
build_property.TargetFrameworkVersion = v8.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property.EntryPointFilePath =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = AdoNetShop
|
||||
build_property.ProjectDir = C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.EffectiveAnalysisLevelStyle = 8.0
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
8
AdoNetShop/obj/Debug/net8.0/AdoNetShop.GlobalUsings.g.cs
Normal file
8
AdoNetShop/obj/Debug/net8.0/AdoNetShop.GlobalUsings.g.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// <auto-generated/>
|
||||
global using System;
|
||||
global using System.Collections.Generic;
|
||||
global using System.IO;
|
||||
global using System.Linq;
|
||||
global using System.Net.Http;
|
||||
global using System.Threading;
|
||||
global using System.Threading.Tasks;
|
||||
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.assets.cache
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.assets.cache
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
c5616ae976ba3d611b5e228dd7cefa521620c5f6c068aa1cf7ad4b73c787d851
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\appsettings.json
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\AdoNetShop.exe
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\AdoNetShop.deps.json
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\AdoNetShop.runtimeconfig.json
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\AdoNetShop.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\AdoNetShop.pdb
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Azure.Core.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Azure.Identity.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Bcl.AsyncInterfaces.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Data.SqlClient.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Configuration.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Configuration.Abstractions.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Configuration.Binder.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Configuration.FileExtensions.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Configuration.Json.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.FileProviders.Abstractions.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.FileProviders.Physical.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.FileSystemGlobbing.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Extensions.Primitives.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Identity.Client.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.Identity.Client.Extensions.Msal.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.Abstractions.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.JsonWebTokens.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.Logging.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.Protocols.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.IdentityModel.Tokens.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\Microsoft.SqlServer.Server.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.Configuration.ConfigurationManager.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.Diagnostics.EventLog.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.IdentityModel.Tokens.Jwt.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.Memory.Data.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.Runtime.Caching.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\System.Security.Cryptography.ProtectedData.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\de\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\es\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\fr\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\it\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\ja\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\ko\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\pt-BR\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\ru\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\zh-Hans\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\zh-Hant\Microsoft.Data.SqlClient.resources.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\unix\lib\net8.0\Microsoft.Data.SqlClient.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win\lib\net8.0\Microsoft.Data.SqlClient.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win-arm\native\Microsoft.Data.SqlClient.SNI.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win-arm64\native\Microsoft.Data.SqlClient.SNI.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win-x64\native\Microsoft.Data.SqlClient.SNI.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win-x86\native\Microsoft.Data.SqlClient.SNI.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win\lib\net8.0\System.Diagnostics.EventLog.Messages.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win\lib\net8.0\System.Diagnostics.EventLog.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\bin\Debug\net8.0\runtimes\win\lib\net8.0\System.Runtime.Caching.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.csproj.AssemblyReference.cache
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.GeneratedMSBuildEditorConfig.editorconfig
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.AssemblyInfoInputs.cache
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.AssemblyInfo.cs
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.csproj.CoreCompileInputs.cache
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.csproj.Up2Date
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\refint\AdoNetShop.dll
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.pdb
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\AdoNetShop.genruntimeconfig.cache
|
||||
C:\Users\ivaiv\OneDrive\Desktop\Artem\AdoNetShop\obj\Debug\net8.0\ref\AdoNetShop.dll
|
||||
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.dll
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.dll
Normal file
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
a4c2f57a00f5817125eb18d0619c0cb75bf436e1533456138e024ef72518b8ce
|
||||
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.pdb
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/AdoNetShop.pdb
Normal file
Binary file not shown.
BIN
AdoNetShop/obj/Debug/net8.0/apphost.exe
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/apphost.exe
Normal file
Binary file not shown.
BIN
AdoNetShop/obj/Debug/net8.0/ref/AdoNetShop.dll
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/ref/AdoNetShop.dll
Normal file
Binary file not shown.
BIN
AdoNetShop/obj/Debug/net8.0/refint/AdoNetShop.dll
Normal file
BIN
AdoNetShop/obj/Debug/net8.0/refint/AdoNetShop.dll
Normal file
Binary file not shown.
2532
AdoNetShop/obj/project.assets.json
Normal file
2532
AdoNetShop/obj/project.assets.json
Normal file
File diff suppressed because it is too large
Load Diff
58
AdoNetShop/obj/project.nuget.cache
Normal file
58
AdoNetShop/obj/project.nuget.cache
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "zA1M7STRDRY=",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Users\\ivaiv\\OneDrive\\Desktop\\Artem\\AdoNetShop\\AdoNetShop.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\azure.core\\1.35.0\\azure.core.1.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\azure.identity\\1.10.3\\azure.identity.1.10.3.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.bcl.asyncinterfaces\\1.1.1\\microsoft.bcl.asyncinterfaces.1.1.1.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.csharp\\4.5.0\\microsoft.csharp.4.5.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.data.sqlclient\\5.2.0\\microsoft.data.sqlclient.5.2.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.data.sqlclient.sni.runtime\\5.2.0\\microsoft.data.sqlclient.sni.runtime.5.2.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.configuration\\8.0.0\\microsoft.extensions.configuration.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\8.0.0\\microsoft.extensions.configuration.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.configuration.binder\\8.0.1\\microsoft.extensions.configuration.binder.8.0.1.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.configuration.fileextensions\\8.0.0\\microsoft.extensions.configuration.fileextensions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.configuration.json\\8.0.0\\microsoft.extensions.configuration.json.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.fileproviders.abstractions\\8.0.0\\microsoft.extensions.fileproviders.abstractions.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.fileproviders.physical\\8.0.0\\microsoft.extensions.fileproviders.physical.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.filesystemglobbing\\8.0.0\\microsoft.extensions.filesystemglobbing.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.extensions.primitives\\8.0.0\\microsoft.extensions.primitives.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identity.client\\4.56.0\\microsoft.identity.client.4.56.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identity.client.extensions.msal\\4.56.0\\microsoft.identity.client.extensions.msal.4.56.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.abstractions\\6.35.0\\microsoft.identitymodel.abstractions.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.jsonwebtokens\\6.35.0\\microsoft.identitymodel.jsonwebtokens.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.logging\\6.35.0\\microsoft.identitymodel.logging.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.protocols\\6.35.0\\microsoft.identitymodel.protocols.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.protocols.openidconnect\\6.35.0\\microsoft.identitymodel.protocols.openidconnect.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.identitymodel.tokens\\6.35.0\\microsoft.identitymodel.tokens.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.netcore.platforms\\5.0.0\\microsoft.netcore.platforms.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.netcore.targets\\1.1.0\\microsoft.netcore.targets.1.1.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.sqlserver.server\\1.0.0\\microsoft.sqlserver.server.1.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.configuration.configurationmanager\\8.0.0\\system.configuration.configurationmanager.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.diagnostics.diagnosticsource\\6.0.1\\system.diagnostics.diagnosticsource.6.0.1.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.diagnostics.eventlog\\8.0.0\\system.diagnostics.eventlog.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.identitymodel.tokens.jwt\\6.35.0\\system.identitymodel.tokens.jwt.6.35.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.io.filesystem.accesscontrol\\5.0.0\\system.io.filesystem.accesscontrol.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.memory\\4.5.4\\system.memory.4.5.4.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.memory.data\\1.0.2\\system.memory.data.1.0.2.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.numerics.vectors\\4.5.0\\system.numerics.vectors.4.5.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.runtime\\4.3.0\\system.runtime.4.3.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.runtime.caching\\8.0.0\\system.runtime.caching.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.security.accesscontrol\\5.0.0\\system.security.accesscontrol.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.security.cryptography.cng\\4.5.0\\system.security.cryptography.cng.4.5.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.security.cryptography.protecteddata\\8.0.0\\system.security.cryptography.protecteddata.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.security.principal.windows\\5.0.0\\system.security.principal.windows.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.text.encoding\\4.3.0\\system.text.encoding.4.3.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.text.encodings.web\\8.0.0\\system.text.encodings.web.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.text.json\\8.0.0\\system.text.json.8.0.0.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\system.threading.tasks.extensions\\4.5.4\\system.threading.tasks.extensions.4.5.4.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.netcore.app.ref\\8.0.30\\microsoft.netcore.app.ref.8.0.30.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.windowsdesktop.app.ref\\8.0.30\\microsoft.windowsdesktop.app.ref.8.0.30.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.aspnetcore.app.ref\\8.0.30\\microsoft.aspnetcore.app.ref.8.0.30.nupkg.sha512",
|
||||
"C:\\Users\\ivaiv\\.nuget\\packages\\microsoft.netcore.app.host.win-x64\\8.0.30\\microsoft.netcore.app.host.win-x64.8.0.30.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
}
|
||||
74
README.md
Normal file
74
README.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# AdoNetShop: Твоя первая лабораторная по ADO.NET 🎓
|
||||
|
||||
Привет! Это учебный проект интернет-магазина. Его главная цель — показать тебе, как работает технология **ADO.NET** изнутри. Мы будем общаться с базой данных Microsoft SQL Server "вручную", без всяких умных прослоек вроде Entity Framework. Это нужно, чтобы ты понял самые основы.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Немного скучной (но нужной) теории простыми словами
|
||||
|
||||
### Что вообще такое ADO.NET?
|
||||
Представь, что твоя программа (на C#) и база данных (SQL Server) говорят на разных языках и живут в разных городах. ADO.NET — это набор инструментов (переводчиков, почтальонов, телефонов), которые позволяют им общаться.
|
||||
Мы не используем ORM (Entity Framework), потому что ORM делает всё за тебя "под капотом". В этой лабе мы лезем под капот сами.
|
||||
|
||||
### Зачем мы это учим?
|
||||
1. **Чтобы понимать, как всё работает на самом деле.** Любая крутая ORM в итоге всё равно превращает свой код в команды ADO.NET.
|
||||
2. **Скорость и контроль.** Иногда нужно написать супер-хитрый и быстрый запрос. Ручной SQL через ADO.NET даст тебе максимальную скорость.
|
||||
|
||||
### Главные герои ADO.NET (Что нужно знать для защиты):
|
||||
|
||||
* 🔌 **`SqlConnection` (Подключение):** Это твой телефонный провод до базы данных. Чтобы что-то сказать базе, нужно поднять трубку (`Open()`), а потом обязательно положить её (`Close()`, или использовать конструкцию `using`).
|
||||
* 📝 **`SqlCommand` (Команда):** Это то, *что* ты говоришь в трубку. Обычно это SQL-запросы (`SELECT`, `INSERT` и т.д.).
|
||||
* 🛡️ **`SqlParameter` (Параметр):** Это твоя защита от злодеев. **Никогда** не склеивай SQL-строку плюсами (типа `"SELECT * FROM Users WHERE Name = " + name`). Хакерам хватит 5 минут, чтобы сломать базу через SQL-инъекцию. Мы передаем переменные *только* через параметры (`@Name`).
|
||||
* 📖 **`SqlDataReader` (Чтец данных):** Представь, что база диктует тебе длиннющий список товаров по телефону. `DataReader` слушает и записывает строку за строкой. Он работает очень быстро, но *только вперед* и требует, чтобы телефонная линия (Connection) была открыта. (Это называется **Connected** подход).
|
||||
* 📦 **`SqlDataAdapter` и `DataTable`:** А это другой подход. `DataAdapter` — это курьер. Он сам едет к базе, забирает *все* данные разом, привозит их тебе и кладет в коробку (`DataTable` в памяти компьютера). После этого он сам вешает трубку. Теперь ты можешь ковыряться в этой коробке сколько угодно, не занимая базу данных. (Это называется **Disconnected** подход).
|
||||
* 🤝 **Транзакция (`SqlTransaction`):** Сделка по принципу "Всё или ничего". Представь перевод денег: списали у тебя, но не зачислили другу. Плохо! Транзакция гарантирует: если база начала делать заказ (создала заказ -> списала товары со склада -> добавила позиции), и вдруг свет моргнул на списании склада — она отменит всё обратно (`Rollback`). Если всё супер — закрепит (`Commit`).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Как запустить эту штуку на твоем компе
|
||||
|
||||
Чтобы проект заработал, тебе нужны две вещи: работающая база данных и запущенный код.
|
||||
|
||||
### Шаг 1: Готовим Базу Данных
|
||||
1. Убедись, что у тебя установлен **Microsoft SQL Server** (подойдет версия Express) и программа для управления им, например, **SQL Server Management Studio (SSMS)**.
|
||||
2. Открой папку `database` в этом проекте.
|
||||
3. Открой SSMS и подключись к своему серверу.
|
||||
4. Выполни скрипты строго по очереди:
|
||||
* ▶️ Сначала выполни код из файла `01_create_database.sql` (Это создаст пустую БД).
|
||||
* ▶️ Затем `02_create_tables.sql` (Создаст нужные таблички).
|
||||
* ▶️ Затем `03_insert_data.sql` (Заполнит их тестовыми товарами и клиентами).
|
||||
|
||||
### Шаг 2: Настраиваем проект
|
||||
1. Открой файл `AdoNetShop/appsettings.json`.
|
||||
2. Найди там строку `ConnectionStrings -> DefaultConnection`.
|
||||
3. Тебе нужно сказать программе, как зовут твой SQL сервер.
|
||||
* Если у тебя обычный разработческий SQL, оставь `Server=localhost`.
|
||||
* Если ты ставил SQL Server Express, скорее всего тебе нужно поменять это на `Server=.\\SQLEXPRESS`.
|
||||
|
||||
### Шаг 3: Запускаем!
|
||||
1. Открой терминал (или командную строку) в папке `AdoNetShop` (там, где лежит файл `.csproj`).
|
||||
2. Напиши команду: `dotnet run`
|
||||
3. Должно появиться красивое консольное меню магазина.
|
||||
|
||||
---
|
||||
|
||||
## 👨🏫 Что показывать преподавателю на защите?
|
||||
|
||||
Препод точно спросит, где и как ты использовал ADO.NET. Вот твоя шпаргалка:
|
||||
|
||||
1. **Как ты подключаешься к базе?**
|
||||
* Покажи файл `Data/DbConnectionFactory.cs`. Расскажи, что строку подключения ты берешь из конфига (это хорошая практика!), а не хардкодишь в коде.
|
||||
2. **Как работает CRUD (Создание, Чтение, Обновление, Удаление)?**
|
||||
* Открой `Data/ProductRepository.cs`.
|
||||
* Покажи метод `GetByIdAsync`. Обрати внимание на `SqlCommand` и то, как ты добавляешь параметры (`command.Parameters.Add`). Расскажи про `SqlDataReader`.
|
||||
* Покажи метод `CreateAsync`. Обрати внимание на `ExecuteScalarAsync` — объясни, что он нужен, чтобы база вернула тебе ID только что созданного товара.
|
||||
3. **Где у тебя транзакция?**
|
||||
* Гордо открывай `Data/OrderRepository.cs` и показывай метод `CreateOrderWithTransactionAsync`.
|
||||
* Объясни: "Сначала мы открываем транзакцию. Потом пытаемся создать заказ и списать товары. Если хоть одного товара нет на складе, я выбрасываю ошибку, код прыгает в блок `catch`, и делает `RollbackAsync()` — отменяет всё. Если всё гладко — `CommitAsync()`".
|
||||
* *Для эффекта:* Запусти программу, нажми пункт "8" и попробуй купить 1000 ноутбуков (их столько нет). Покажи, что заказ не создался.
|
||||
4. **А где Disconnected подход (отсоединенная модель)?**
|
||||
* Открой пункт меню "10" в запущенной программе.
|
||||
* Открой метод `GetProductsTableAsync` в `ProductRepository.cs`.
|
||||
* Покажи класс `SqlDataAdapter` и `DataTable`. Объясни, что курьер (адаптер) сам сбегал в базу, залил всё в таблицу и разорвал связь с БД.
|
||||
|
||||
Удачи на защите! Ты справишься! 💪
|
||||
11
database/01_create_database.sql
Normal file
11
database/01_create_database.sql
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
-- 01_create_database.sql
|
||||
-- Скрипт для создания базы данных
|
||||
|
||||
USE master;
|
||||
GO
|
||||
|
||||
IF NOT EXISTS (SELECT name FROM sys.databases WHERE name = N'AdoNetShop')
|
||||
BEGIN
|
||||
CREATE DATABASE [AdoNetShop];
|
||||
END
|
||||
GO
|
||||
85
database/02_create_tables.sql
Normal file
85
database/02_create_tables.sql
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
-- 02_create_tables.sql
|
||||
-- Скрипт для создания таблиц
|
||||
|
||||
USE [AdoNetShop];
|
||||
GO
|
||||
|
||||
-- Таблица Categories
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Categories')
|
||||
BEGIN
|
||||
CREATE TABLE Categories (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
Name NVARCHAR(100) NOT NULL
|
||||
);
|
||||
END
|
||||
GO
|
||||
|
||||
-- Таблица Products
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Products')
|
||||
BEGIN
|
||||
CREATE TABLE Products (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
Name NVARCHAR(200) NOT NULL,
|
||||
Description NVARCHAR(MAX) NULL,
|
||||
Price DECIMAL(18, 2) NOT NULL CHECK (Price > 0),
|
||||
StockQuantity INT NOT NULL DEFAULT 0 CHECK (StockQuantity >= 0),
|
||||
CategoryId INT NOT NULL,
|
||||
FOREIGN KEY (CategoryId) REFERENCES Categories(Id)
|
||||
);
|
||||
END
|
||||
GO
|
||||
|
||||
-- Таблица Customers
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Customers')
|
||||
BEGIN
|
||||
CREATE TABLE Customers (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
Name NVARCHAR(100) NOT NULL,
|
||||
Email NVARCHAR(100) NOT NULL UNIQUE,
|
||||
Phone NVARCHAR(20) NULL
|
||||
);
|
||||
END
|
||||
GO
|
||||
|
||||
-- Таблица Orders
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'Orders')
|
||||
BEGIN
|
||||
CREATE TABLE Orders (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
CustomerId INT NOT NULL,
|
||||
OrderDate DATETIME2 NOT NULL DEFAULT GETDATE(),
|
||||
Status NVARCHAR(50) NOT NULL DEFAULT 'New',
|
||||
TotalAmount DECIMAL(18, 2) NOT NULL DEFAULT 0 CHECK (TotalAmount >= 0),
|
||||
FOREIGN KEY (CustomerId) REFERENCES Customers(Id)
|
||||
);
|
||||
END
|
||||
GO
|
||||
|
||||
-- Таблица OrderItems
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'OrderItems')
|
||||
BEGIN
|
||||
CREATE TABLE OrderItems (
|
||||
Id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
OrderId INT NOT NULL,
|
||||
ProductId INT NOT NULL,
|
||||
Quantity INT NOT NULL CHECK (Quantity > 0),
|
||||
Price DECIMAL(18, 2) NOT NULL CHECK (Price > 0),
|
||||
FOREIGN KEY (OrderId) REFERENCES Orders(Id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (ProductId) REFERENCES Products(Id)
|
||||
);
|
||||
END
|
||||
GO
|
||||
|
||||
-- Индексы для внешних ключей (улучшают производительность JOIN'ов)
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Products_CategoryId')
|
||||
CREATE INDEX IX_Products_CategoryId ON Products(CategoryId);
|
||||
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_Orders_CustomerId')
|
||||
CREATE INDEX IX_Orders_CustomerId ON Orders(CustomerId);
|
||||
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_OrderItems_OrderId')
|
||||
CREATE INDEX IX_OrderItems_OrderId ON OrderItems(OrderId);
|
||||
|
||||
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE name = 'IX_OrderItems_ProductId')
|
||||
CREATE INDEX IX_OrderItems_ProductId ON OrderItems(ProductId);
|
||||
GO
|
||||
42
database/03_insert_data.sql
Normal file
42
database/03_insert_data.sql
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
-- 03_insert_data.sql
|
||||
-- Скрипт для вставки тестовых данных
|
||||
|
||||
USE [AdoNetShop];
|
||||
GO
|
||||
|
||||
-- Очистка таблиц перед вставкой (опционально, для чистоты эксперимента)
|
||||
-- Отключаем проверку внешних ключей
|
||||
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
|
||||
EXEC sp_MSForEachTable 'DELETE FROM ?'
|
||||
EXEC sp_MSForEachTable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
|
||||
-- Сброс identity
|
||||
DBCC CHECKIDENT ('Categories', RESEED, 0);
|
||||
DBCC CHECKIDENT ('Products', RESEED, 0);
|
||||
DBCC CHECKIDENT ('Customers', RESEED, 0);
|
||||
DBCC CHECKIDENT ('Orders', RESEED, 0);
|
||||
DBCC CHECKIDENT ('OrderItems', RESEED, 0);
|
||||
GO
|
||||
|
||||
|
||||
-- Добавляем категории
|
||||
INSERT INTO Categories (Name) VALUES
|
||||
('Laptops'),
|
||||
('Smartphones'),
|
||||
('Accessories');
|
||||
|
||||
-- Добавляем товары
|
||||
INSERT INTO Products (Name, Description, Price, StockQuantity, CategoryId) VALUES
|
||||
('Laptop Dell XPS 15', 'High performance laptop', 1500.00, 10, 1),
|
||||
('MacBook Pro 14', 'Apple laptop with M2 chip', 1999.99, 5, 1),
|
||||
('iPhone 14 Pro', 'Latest Apple smartphone', 999.00, 20, 2),
|
||||
('Samsung Galaxy S23', 'Flagship Android phone', 899.50, 15, 2),
|
||||
('Wireless Mouse', 'Ergonomic wireless mouse', 25.00, 50, 3),
|
||||
('USB-C Hub', 'Multi-port adapter', 45.00, 30, 3);
|
||||
|
||||
-- Добавляем клиентов
|
||||
INSERT INTO Customers (Name, Email, Phone) VALUES
|
||||
('Ivan Ivanov', 'ivan@example.com', '+1234567890'),
|
||||
('Petr Petrov', 'petr@example.com', '+0987654321');
|
||||
|
||||
-- Заказы добавлять не будем, создадим их из кода, чтобы протестировать транзакции
|
||||
GO
|
||||
28
database/04_queries.sql
Normal file
28
database/04_queries.sql
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- 04_queries.sql
|
||||
-- Примеры запросов
|
||||
|
||||
USE [AdoNetShop];
|
||||
GO
|
||||
|
||||
-- Получить все товары с названиями категорий
|
||||
SELECT
|
||||
p.Id,
|
||||
p.Name,
|
||||
p.Price,
|
||||
p.StockQuantity,
|
||||
c.Name AS CategoryName
|
||||
FROM Products p
|
||||
JOIN Categories c ON p.CategoryId = c.Id;
|
||||
|
||||
-- Получить все заказы клиента с деталями
|
||||
SELECT
|
||||
o.Id AS OrderId,
|
||||
o.OrderDate,
|
||||
o.TotalAmount,
|
||||
p.Name AS ProductName,
|
||||
oi.Quantity,
|
||||
oi.Price
|
||||
FROM Orders o
|
||||
JOIN OrderItems oi ON o.Id = oi.OrderId
|
||||
JOIN Products p ON oi.ProductId = p.Id
|
||||
WHERE o.CustomerId = 1;
|
||||
38
database/05_procedures.sql
Normal file
38
database/05_procedures.sql
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
-- 05_procedures.sql
|
||||
-- Создание хранимых процедур
|
||||
|
||||
USE [AdoNetShop];
|
||||
GO
|
||||
|
||||
-- Процедура для получения товаров по категории
|
||||
CREATE OR ALTER PROCEDURE GetProductsByCategory
|
||||
@CategoryId INT
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
SELECT Id, Name, Description, Price, StockQuantity, CategoryId
|
||||
FROM Products
|
||||
WHERE CategoryId = @CategoryId;
|
||||
END
|
||||
GO
|
||||
|
||||
-- Процедура для безопасного обновления цены
|
||||
CREATE OR ALTER PROCEDURE UpdateProductPrice
|
||||
@ProductId INT,
|
||||
@NewPrice DECIMAL(18,2)
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
IF @NewPrice <= 0
|
||||
BEGIN
|
||||
RAISERROR ('Цена должна быть больше нуля.', 16, 1);
|
||||
RETURN;
|
||||
END
|
||||
|
||||
UPDATE Products
|
||||
SET Price = @NewPrice
|
||||
WHERE Id = @ProductId;
|
||||
END
|
||||
GO
|
||||
19
database/06_test.sql
Normal file
19
database/06_test.sql
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
-- 06_test.sql
|
||||
-- Тестовый скрипт (выполнять вручную для проверки базы)
|
||||
|
||||
USE [AdoNetShop];
|
||||
GO
|
||||
|
||||
SELECT * FROM Categories;
|
||||
SELECT * FROM Products;
|
||||
SELECT * FROM Customers;
|
||||
|
||||
-- Тест процедуры
|
||||
EXEC GetProductsByCategory @CategoryId = 1;
|
||||
|
||||
-- Тест обновления цены (успешный)
|
||||
EXEC UpdateProductPrice @ProductId = 1, @NewPrice = 1450.00;
|
||||
SELECT * FROM Products WHERE Id = 1;
|
||||
|
||||
-- Тест обновления цены (ошибка)
|
||||
-- EXEC UpdateProductPrice @ProductId = 1, @NewPrice = -10.00;
|
||||
Loading…
Reference in New Issue
Block a user