diff --git a/HomeWork22/HomeWork22.sln b/HomeWork22/HomeWork22.sln new file mode 100644 index 0000000..9490613 --- /dev/null +++ b/HomeWork22/HomeWork22.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34525.116 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HomeWork22", "HomeWork22\HomeWork22.csproj", "{CFCCD84A-B798-4733-978A-B3098BB61F1F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CFCCD84A-B798-4733-978A-B3098BB61F1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CFCCD84A-B798-4733-978A-B3098BB61F1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CFCCD84A-B798-4733-978A-B3098BB61F1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CFCCD84A-B798-4733-978A-B3098BB61F1F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7D596900-7DD0-4AB6-A8B6-681469160DEE} + EndGlobalSection +EndGlobal diff --git a/HomeWork22/HomeWork22/App.cs b/HomeWork22/HomeWork22/App.cs new file mode 100644 index 0000000..491f313 --- /dev/null +++ b/HomeWork22/HomeWork22/App.cs @@ -0,0 +1,76 @@ +using HomeWork22.Dtos; +using HomeWork22.Models; +using HomeWork22.Services.Abstracts; + +namespace HomeWork22 +{ + internal class App + { + private readonly IOrderService _orderService; + private readonly ICostumerService _costumerService; + private readonly IProductService _productService; + public App(IProductService productService, ICostumerService costumerService, IOrderService orderService) + { + _costumerService = costumerService; + _orderService = orderService; + _productService = productService; + } + public async Task StartAsync() + { + var idConstumer = await _costumerService.AddCostumerAsync("Max", "Babych"); + + var costumer = await _costumerService.GetCostumerAsync(idConstumer); + + costumer = await _costumerService.UpdateCostumerAsync(idConstumer, "Oleg"); + + var idLimon = await _productService.AddProductAsync("Limon", 15.25); + + var idOrange = await _productService.AddProductAsync("Orange", 10.50); + + await _productService.UpdataProductAsync(idOrange, name: "Limon", price: 11); + + var productLimon = await _productService.GetProductAsync(idLimon); + + var productOrange = await _productService.GetProductAsync(idOrange); + + List orderItems = new List() + { + new OrderItem() + { + Count = 5, + Product = productLimon, + ProductId = productLimon.Id, + }, + new OrderItem() + { + Count = 10, + Product = productOrange, + ProductId = productOrange.Id, + } + }; + + var idOrder = await _orderService.AddOrderAsync(idConstumer, orderItems); + + var order = await _orderService.GetOrderAsync(idOrder); + + var request = new RequestPage() + { + Name = "Limon", + PageNamber = 1, + PageSize = 20, + PriceMax = 10, + PriceMin = 5, + }; + + await _productService.GetViewProductListAsync(request); + + await _orderService.DeleteOrderAsync(idOrder); + + await _costumerService.DeleteCostumerAsync(idConstumer); + + await _productService.DeleteProduct(idLimon); + + await _productService.DeleteProduct(idOrange); + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/ApplicatDbContext.cs b/HomeWork22/HomeWork22/Datas/ApplicatDbContext.cs new file mode 100644 index 0000000..09bc5ea --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/ApplicatDbContext.cs @@ -0,0 +1,27 @@ +using HomeWork22.Datas.Entities; +using HomeWork22.Datas.EntitiesConfigurations; +using Microsoft.EntityFrameworkCore; + +namespace HomeWork22.Datas +{ + internal class ApplicatDbContext : DbContext + { + public ApplicatDbContext(DbContextOptions options) + : base(options) + {} + + public DbSet Costumers { get; set; } = null!; + public DbSet Orders { get; set; } = null!; + public DbSet OrderItems { get; set; } = null!; + public DbSet Products { get; set; } = null!; + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfiguration(new CostumerEntityConfiguration()); + modelBuilder.ApplyConfiguration(new OrderEntityConfiguration()); + modelBuilder.ApplyConfiguration(new OrderItemEntityConguration()); + modelBuilder.ApplyConfiguration(new ProductEntityConfiguration()); + modelBuilder.UseHiLo(); + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/ApplicatDbContextFactory.cs b/HomeWork22/HomeWork22/Datas/ApplicatDbContextFactory.cs new file mode 100644 index 0000000..74ca62e --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/ApplicatDbContextFactory.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Microsoft.Extensions.Configuration; + +namespace HomeWork22.Datas +{ + internal class ApplicatDbContextFactory : IDesignTimeDbContextFactory + { + public ApplicatDbContext CreateDbContext(string[] args) + { + var optionalBuilder = new DbContextOptionsBuilder(); + + var builder = new ConfigurationBuilder(); + builder.SetBasePath(Directory.GetCurrentDirectory()); + + var config = builder + .AddJsonFile("config.json") + .Build(); + + var connectionString = config.GetConnectionString("DefaultConnection"); + optionalBuilder + .UseSqlServer(connectionString, option => + option + .CommandTimeout((int)TimeSpan + .FromMinutes(10) + .TotalSeconds)); + + return new ApplicatDbContext(optionalBuilder.Options); + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/Entities/CostumerEntity.cs b/HomeWork22/HomeWork22/Datas/Entities/CostumerEntity.cs new file mode 100644 index 0000000..95b733b --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/Entities/CostumerEntity.cs @@ -0,0 +1,11 @@ +namespace HomeWork22.Datas.Entities +{ + internal class CostumerEntity + { + public int Id { get; set; } + public string? FirstName { get; set; } + public string? LastName { get; set; } + + public ICollection Orders { get; set; } = new List(); + } +} diff --git a/HomeWork22/HomeWork22/Datas/Entities/OrderEntity.cs b/HomeWork22/HomeWork22/Datas/Entities/OrderEntity.cs new file mode 100644 index 0000000..69748f5 --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/Entities/OrderEntity.cs @@ -0,0 +1,11 @@ +namespace HomeWork22.Datas.Entities +{ + internal class OrderEntity + { + public int Id { get; set; } + public int CostumerId { get; set; } + public CostumerEntity? Costumer { get; set; } + + public ICollection OrderItems { get; set; } = new List(); + } +} diff --git a/HomeWork22/HomeWork22/Datas/Entities/OrderItemEntity.cs b/HomeWork22/HomeWork22/Datas/Entities/OrderItemEntity.cs new file mode 100644 index 0000000..3361f85 --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/Entities/OrderItemEntity.cs @@ -0,0 +1,12 @@ +namespace HomeWork22.Datas.Entities +{ + internal class OrderItemEntity + { + public int Id { get; set; } + public int Count { get; set; } + public int OrderId { get; set; } + public OrderEntity? Order { get; set; } + public int ProductId { get; set; } + public ProductEntity? Product { get; set; } + } +} diff --git a/HomeWork22/HomeWork22/Datas/Entities/ProductEntity.cs b/HomeWork22/HomeWork22/Datas/Entities/ProductEntity.cs new file mode 100644 index 0000000..23e09a2 --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/Entities/ProductEntity.cs @@ -0,0 +1,11 @@ +namespace HomeWork22.Datas.Entities +{ + internal class ProductEntity + { + public int Id { get; set; } + public string Name { get; set; } = null!; + public double Price { get; set; } + + public ICollection OrderItems { get; set; } = new List(); + } +} diff --git a/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/CostumerEntityConfiguration.cs b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/CostumerEntityConfiguration.cs new file mode 100644 index 0000000..8ea331a --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/CostumerEntityConfiguration.cs @@ -0,0 +1,23 @@ +using HomeWork22.Datas.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HomeWork22.Datas.EntitiesConfigurations +{ + internal class CostumerEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + + builder + .Property(p => p.FirstName) + .HasMaxLength(50); + + builder + .Property(p => p.LastName) + .IsRequired() + .HasMaxLength(50); + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderEntityConfiguration.cs b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderEntityConfiguration.cs new file mode 100644 index 0000000..ece0463 --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderEntityConfiguration.cs @@ -0,0 +1,21 @@ +using HomeWork22.Datas.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HomeWork22.Datas.EntitiesConfigurations +{ + internal class OrderEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x => x.Id); + + builder + .HasOne(o => o.Costumer) + .WithMany(m => m.Orders) + .HasForeignKey(o => o.CostumerId) + .OnDelete(DeleteBehavior.Cascade); + + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderItemEntityConguration.cs b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderItemEntityConguration.cs new file mode 100644 index 0000000..1212947 --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/OrderItemEntityConguration.cs @@ -0,0 +1,30 @@ +using HomeWork22.Datas.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HomeWork22.Datas.EntitiesConfigurations +{ + internal class OrderItemEntityConguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x=>x.Id); + + builder + .Property(x => x.Count) + .IsRequired(); + + builder + .HasOne(x => x.Order) + .WithMany(x => x.OrderItems) + .HasForeignKey(x=>x.OrderId) + .OnDelete(DeleteBehavior.Cascade); + + builder + .HasOne(x=>x.Product) + .WithMany(x => x.OrderItems) + .HasForeignKey(x=>x.ProductId) + .OnDelete(DeleteBehavior.Cascade); + } + } +} diff --git a/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/ProductEntityConfiguration.cs b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/ProductEntityConfiguration.cs new file mode 100644 index 0000000..50a245d --- /dev/null +++ b/HomeWork22/HomeWork22/Datas/EntitiesConfigurations/ProductEntityConfiguration.cs @@ -0,0 +1,23 @@ +using HomeWork22.Datas.Entities; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; + +namespace HomeWork22.Datas.EntitiesConfigurations +{ + internal class ProductEntityConfiguration : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.HasKey(x=>x.Id); + + builder + .Property(x => x.Name) + .IsRequired() + .HasMaxLength(100); + + builder + .Property(x => x.Price) + .IsRequired(); + } + } +} diff --git a/HomeWork22/HomeWork22/Dtos/PageDto.cs b/HomeWork22/HomeWork22/Dtos/PageDto.cs new file mode 100644 index 0000000..02b8664 --- /dev/null +++ b/HomeWork22/HomeWork22/Dtos/PageDto.cs @@ -0,0 +1,8 @@ +namespace HomeWork22.Dtos +{ + internal class PageDto + { + public int PageNamber = 1; + public int PageSize = 20; + } +} diff --git a/HomeWork22/HomeWork22/Dtos/RequestPage.cs b/HomeWork22/HomeWork22/Dtos/RequestPage.cs new file mode 100644 index 0000000..de9e80f --- /dev/null +++ b/HomeWork22/HomeWork22/Dtos/RequestPage.cs @@ -0,0 +1,10 @@ +namespace HomeWork22.Dtos +{ + internal class RequestPage : PageDto + { + public string? Name { get; set; } = string.Empty; + public double PriceMax { get; set; } = 0; + public double PriceMin { get; set;} = 0; + + } +} diff --git a/HomeWork22/HomeWork22/Dtos/ResponsPage.cs b/HomeWork22/HomeWork22/Dtos/ResponsPage.cs new file mode 100644 index 0000000..4bdd91b --- /dev/null +++ b/HomeWork22/HomeWork22/Dtos/ResponsPage.cs @@ -0,0 +1,26 @@ +namespace HomeWork22.Dtos +{ + internal class ResponsPage : PageDto + { + public ResponsPage() + { } + + public int TotalItems => Items.Count; + + public int TotalPages + { + get + { + return (int)Math.Ceiling((double)TotalItems / PageSize); + } + } + + public List Items { get; set; } + public ResponsPage(List items, RequestPage request) + { + Items = items; + PageSize = request.PageSize; + PageNamber = request.PageNamber; + } + } +} diff --git a/HomeWork22/HomeWork22/HomeWork22.csproj b/HomeWork22/HomeWork22/HomeWork22.csproj new file mode 100644 index 0000000..34c476b --- /dev/null +++ b/HomeWork22/HomeWork22/HomeWork22.csproj @@ -0,0 +1,38 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + Always + + + + diff --git a/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.Designer.cs b/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.Designer.cs new file mode 100644 index 0000000..6f1b031 --- /dev/null +++ b/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.Designer.cs @@ -0,0 +1,164 @@ +// +using HomeWork22.Datas; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace HomeWork22.Migrations +{ + [DbContext(typeof(ApplicatDbContext))] + [Migration("20240329172908_CreateMig")] + partial class CreateMig + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseHiLo(modelBuilder, "EntityFrameworkHiLoSequence"); + + modelBuilder.HasSequence("EntityFrameworkHiLoSequence") + .IncrementsBy(10); + + modelBuilder.Entity("HomeWork22.Datas.Entities.CostumerEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("FirstName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Costumers"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("CostumerId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CostumerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderItemEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("ProductId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.HasIndex("ProductId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.ProductEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.HasOne("HomeWork22.Datas.Entities.CostumerEntity", "Costumer") + .WithMany("Orders") + .HasForeignKey("CostumerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Costumer"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderItemEntity", b => + { + b.HasOne("HomeWork22.Datas.Entities.OrderEntity", "Order") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HomeWork22.Datas.Entities.ProductEntity", "Product") + .WithMany("OrderItems") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.CostumerEntity", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.Navigation("OrderItems"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.ProductEntity", b => + { + b.Navigation("OrderItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.cs b/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.cs new file mode 100644 index 0000000..92cb0e7 --- /dev/null +++ b/HomeWork22/HomeWork22/Migrations/20240329172908_CreateMig.cs @@ -0,0 +1,122 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace HomeWork22.Migrations +{ + /// + public partial class CreateMig : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateSequence( + name: "EntityFrameworkHiLoSequence", + incrementBy: 10); + + migrationBuilder.CreateTable( + name: "Costumers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false), + FirstName = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: true), + LastName = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Costumers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Products", + columns: table => new + { + Id = table.Column(type: "int", nullable: false), + Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Price = table.Column(type: "float", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Products", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(type: "int", nullable: false), + CostumerId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + table.ForeignKey( + name: "FK_Orders_Costumers_CostumerId", + column: x => x.CostumerId, + principalTable: "Costumers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderItems", + columns: table => new + { + Id = table.Column(type: "int", nullable: false), + Count = table.Column(type: "int", nullable: false), + OrderId = table.Column(type: "int", nullable: false), + ProductId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderItems", x => x.Id); + table.ForeignKey( + name: "FK_OrderItems_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_OrderItems_Products_ProductId", + column: x => x.ProductId, + principalTable: "Products", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_OrderId", + table: "OrderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_ProductId", + table: "OrderItems", + column: "ProductId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_CostumerId", + table: "Orders", + column: "CostumerId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "OrderItems"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Products"); + + migrationBuilder.DropTable( + name: "Costumers"); + + migrationBuilder.DropSequence( + name: "EntityFrameworkHiLoSequence"); + } + } +} diff --git a/HomeWork22/HomeWork22/Migrations/ApplicatDbContextModelSnapshot.cs b/HomeWork22/HomeWork22/Migrations/ApplicatDbContextModelSnapshot.cs new file mode 100644 index 0000000..4569300 --- /dev/null +++ b/HomeWork22/HomeWork22/Migrations/ApplicatDbContextModelSnapshot.cs @@ -0,0 +1,161 @@ +// +using HomeWork22.Datas; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace HomeWork22.Migrations +{ + [DbContext(typeof(ApplicatDbContext))] + partial class ApplicatDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseHiLo(modelBuilder, "EntityFrameworkHiLoSequence"); + + modelBuilder.HasSequence("EntityFrameworkHiLoSequence") + .IncrementsBy(10); + + modelBuilder.Entity("HomeWork22.Datas.Entities.CostumerEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("FirstName") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Costumers"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("CostumerId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CostumerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderItemEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("Count") + .HasColumnType("int"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("ProductId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.HasIndex("ProductId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.ProductEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseHiLo(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Price") + .HasColumnType("float"); + + b.HasKey("Id"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.HasOne("HomeWork22.Datas.Entities.CostumerEntity", "Costumer") + .WithMany("Orders") + .HasForeignKey("CostumerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Costumer"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderItemEntity", b => + { + b.HasOne("HomeWork22.Datas.Entities.OrderEntity", "Order") + .WithMany("OrderItems") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HomeWork22.Datas.Entities.ProductEntity", "Product") + .WithMany("OrderItems") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.CostumerEntity", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.OrderEntity", b => + { + b.Navigation("OrderItems"); + }); + + modelBuilder.Entity("HomeWork22.Datas.Entities.ProductEntity", b => + { + b.Navigation("OrderItems"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HomeWork22/HomeWork22/Models/Costumer.cs b/HomeWork22/HomeWork22/Models/Costumer.cs new file mode 100644 index 0000000..2975082 --- /dev/null +++ b/HomeWork22/HomeWork22/Models/Costumer.cs @@ -0,0 +1,10 @@ +namespace HomeWork22.Models +{ + internal class Costumer + { + public int Id { get; set; } + public string? Lastname { get; set; } + public string? Firstname { get; set; } + public string? Fullname { get; set; } + } +} diff --git a/HomeWork22/HomeWork22/Models/Order.cs b/HomeWork22/HomeWork22/Models/Order.cs new file mode 100644 index 0000000..2fd607d --- /dev/null +++ b/HomeWork22/HomeWork22/Models/Order.cs @@ -0,0 +1,9 @@ +namespace HomeWork22.Models +{ + internal class Order + { + public int Id { get; set; } + public Costumer? Costumer { get; set; } + public IEnumerable? OrderItem { get; set; } + } +} diff --git a/HomeWork22/HomeWork22/Models/OrderItem.cs b/HomeWork22/HomeWork22/Models/OrderItem.cs new file mode 100644 index 0000000..fb3b387 --- /dev/null +++ b/HomeWork22/HomeWork22/Models/OrderItem.cs @@ -0,0 +1,9 @@ +namespace HomeWork22.Models +{ + internal class OrderItem + { + public int Count { get; set; } + public int ProductId { get; set; } + public Product? Product { get; set; } + } +} diff --git a/HomeWork22/HomeWork22/Models/Product.cs b/HomeWork22/HomeWork22/Models/Product.cs new file mode 100644 index 0000000..0050dc9 --- /dev/null +++ b/HomeWork22/HomeWork22/Models/Product.cs @@ -0,0 +1,9 @@ +namespace HomeWork22.Models +{ + internal class Product + { + public int Id { get; set; } + public string Name { get; set; } = null!; + public double Price { get; set; } + } +} diff --git a/HomeWork22/HomeWork22/Program.cs b/HomeWork22/HomeWork22/Program.cs new file mode 100644 index 0000000..1e81a3b --- /dev/null +++ b/HomeWork22/HomeWork22/Program.cs @@ -0,0 +1,61 @@ +using HomeWork22.Datas; +using HomeWork22.DbWrappers; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Repositories; +using HomeWork22.Repositories.Abstractions; +using HomeWork22.Services; +using HomeWork22.Services.Abstracts; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace HomeWork22 +{ + class Program + { + static async Task Main(string[] args) + { + void ConfigureService(ServiceCollection serviceCollection, IConfiguration configuration) + { + var connectionString = configuration.GetConnectionString("DefaultConnection"); + serviceCollection + .AddDbContextFactory(option => + option + .UseSqlServer(connectionString)); + + serviceCollection + .AddLogging(login => login.AddConsole()) + .AddScoped, DbContextWrapper>() + .AddTransient() + .AddTransient() + .AddTransient() + .AddTransient() + .AddTransient() + .AddTransient() + .AddTransient(); + } + + IConfiguration configuration = new ConfigurationBuilder() + .AddJsonFile("config.json") + .Build(); + + var serviceCollection = new ServiceCollection(); + ConfigureService (serviceCollection, configuration); + var provider = serviceCollection.BuildServiceProvider(); + + var isNeedMigration = configuration + .GetSection("Migration") + .GetSection("IsNeedMigration"); + + if (bool.Parse(isNeedMigration.Value!)) + { + var dbContext = provider.GetService(); + await dbContext!.Database.MigrateAsync(); + } + + var app = provider.GetService(); + await app!.StartAsync(); + } + } +} diff --git a/HomeWork22/HomeWork22/Repositories/Abstractions/ICostumerRepository.cs b/HomeWork22/HomeWork22/Repositories/Abstractions/ICostumerRepository.cs new file mode 100644 index 0000000..baeab6c --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/Abstractions/ICostumerRepository.cs @@ -0,0 +1,15 @@ +using HomeWork22.Datas.Entities; + +namespace HomeWork22.Repositories.Abstractions +{ + internal interface ICostumerRepository + { + public Task AddCostumerAsync(string lastname, string firstname); + public Task GetCostumerAsync(int id); + public Task UpdateCostumerAsync( + int id, + string lastname = null!, + string firstname = null!); + public Task DeleteCostumerAsync(int id); + } +} diff --git a/HomeWork22/HomeWork22/Repositories/Abstractions/IOrderRepository.cs b/HomeWork22/HomeWork22/Repositories/Abstractions/IOrderRepository.cs new file mode 100644 index 0000000..7c10a63 --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/Abstractions/IOrderRepository.cs @@ -0,0 +1,14 @@ +using HomeWork22.Datas.Entities; +using HomeWork22.Models; + +namespace HomeWork22.Repositories.Abstractions +{ + internal interface IOrderRepository + { + public Task AddOrderAsync(int id, List orderItemList); + public Task GetOrder(int id); + public Task?> GetOrderByCostumerId(int id); + public Task UpDataOrderAsync(int id, List orderItem); + public Task DeleteOrderAsync(int id); + } +} diff --git a/HomeWork22/HomeWork22/Repositories/Abstractions/IProductRepository.cs b/HomeWork22/HomeWork22/Repositories/Abstractions/IProductRepository.cs new file mode 100644 index 0000000..156ce29 --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/Abstractions/IProductRepository.cs @@ -0,0 +1,18 @@ +using HomeWork22.Datas.Entities; +using HomeWork22.Dtos; + +namespace HomeWork22.Repositories.Abstractions +{ + internal interface IProductRepository + { + public Task AddProductAsync(string name, double price); + public Task GetProductAsync(int id); + public Task DeleteProductAsync(int id); + public Task UpdataProductAsync( + int id, + string name = null!, + double price = 0); + + public Task> GetProductListAsync(RequestPage request); + } +} diff --git a/HomeWork22/HomeWork22/Repositories/CostumerRepository.cs b/HomeWork22/HomeWork22/Repositories/CostumerRepository.cs new file mode 100644 index 0000000..3cb625c --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/CostumerRepository.cs @@ -0,0 +1,72 @@ +using HomeWork22.Datas; +using HomeWork22.Datas.Entities; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Models; +using HomeWork22.Repositories.Abstractions; +using Microsoft.EntityFrameworkCore; + +namespace HomeWork22.Repositories +{ + internal class CostumerRepository : ICostumerRepository + { + private readonly ApplicatDbContext _dbContext; + + public CostumerRepository(IDbContextWrapper dbContextWrapper) + { + _dbContext = dbContextWrapper.DbContext; + } + + public async Task AddCostumerAsync(string lastname, string firstname) + { + var costumer = new CostumerEntity() + { + FirstName = firstname, + LastName = lastname + }; + + var costm = await _dbContext.AddAsync(costumer); + + await _dbContext.SaveChangesAsync(); + + return costm.Entity.Id; + } + + public async Task UpdateCostumerAsync(int id, string lastname = null!, string firstname = null!) + { + var costumer = await GetCostumerAsync(id); + + if (costumer is null) + { + return null; + } + + costumer.LastName = lastname is null ? costumer.LastName : lastname; + + costumer.FirstName = firstname is null ? costumer.FirstName : firstname; + + await _dbContext.SaveChangesAsync(); + + return costumer; + } + + public async Task DeleteCostumerAsync(int id) + { + var costumer = await GetCostumerAsync(id); + + if(costumer is null) + { + return null; + } + + var status = _dbContext.Costumers.Remove(costumer); + await _dbContext.SaveChangesAsync(); + + return status.ToString(); + } + + public async Task GetCostumerAsync(int id) + { + return await _dbContext.Costumers.FirstOrDefaultAsync(c => c.Id == id); + } + } +} diff --git a/HomeWork22/HomeWork22/Repositories/OrderRepository.cs b/HomeWork22/HomeWork22/Repositories/OrderRepository.cs new file mode 100644 index 0000000..ec2beb4 --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/OrderRepository.cs @@ -0,0 +1,83 @@ +using HomeWork22.Datas; +using HomeWork22.Datas.Entities; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Models; +using HomeWork22.Repositories.Abstractions; +using Microsoft.EntityFrameworkCore; + +namespace HomeWork22.Repositories +{ + internal class OrderRepository : IOrderRepository + { + private readonly ApplicatDbContext _dbContext; + + public OrderRepository(IDbContextWrapper dbContextWrapper) + { + _dbContext = dbContextWrapper.DbContext; + } + + public async Task AddOrderAsync(int id, List orderItemList) + { + var order = await _dbContext.Orders + .AddAsync(new OrderEntity() + { + CostumerId = id, + }); + + await _dbContext + .OrderItems + .AddRangeAsync(orderItemList.Select(s => + new OrderItemEntity() + { + Count = s.Count, + OrderId = order.Entity.Id, + ProductId = s.ProductId, + })); + + await _dbContext.SaveChangesAsync(); + + return order.Entity.Id; + } + + public async Task UpDataOrderAsync(int id, List orderItem) + { + var orderUp = await GetOrder(id); + + orderUp.OrderItems = orderItem; + + await _dbContext.SaveChangesAsync(); + + return orderUp; + } + + public async Task DeleteOrderAsync(int id) + { + var order = await GetOrder(id); + + if (order is null) + { + return null; + } + + var status = _dbContext.Orders.Remove(order); + + await _dbContext.SaveChangesAsync(); + return status.ToString(); + } + + public async Task GetOrder(int id) + { + return await _dbContext.Orders + .Include(i => i.OrderItems) + .FirstOrDefaultAsync(x=>x.Id == id); + } + + public async Task?> GetOrderByCostumerId(int id) + { + return await _dbContext.Orders + .Include(x=>x.OrderItems) + .Where(x=>x.CostumerId==id) + .ToListAsync(); + } + } +} diff --git a/HomeWork22/HomeWork22/Repositories/ProductRepository.cs b/HomeWork22/HomeWork22/Repositories/ProductRepository.cs new file mode 100644 index 0000000..4e04cfc --- /dev/null +++ b/HomeWork22/HomeWork22/Repositories/ProductRepository.cs @@ -0,0 +1,73 @@ +using HomeWork22.Datas; +using HomeWork22.Datas.Entities; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Dtos; +using HomeWork22.Repositories.Abstractions; +using Microsoft.EntityFrameworkCore; + +namespace HomeWork22.Repositories +{ + internal class ProductRepository : IProductRepository + { + private readonly ApplicatDbContext _dbContext; + + public ProductRepository(IDbContextWrapper dbContextWrapper) + { + _dbContext = dbContextWrapper.DbContext; + } + public async Task AddProductAsync(string name, double price) + { + var product = new ProductEntity() + { + Name = name, + Price = price + }; + + var products = await _dbContext.Products.AddAsync(product); + await _dbContext.SaveChangesAsync(); + + return products.Entity.Id; + } + + public async Task UpdataProductAsync(int id, string name, double price) + { + var product = await GetProductAsync(id); + + product!.Price = price == 0 ? product.Price : price; + product.Name = name is null ? product.Name : name; + + await _dbContext.SaveChangesAsync(); + + return product; + } + + public async Task DeleteProductAsync(int id) + { + var product = await GetProductAsync(id); + if (product is null) + { + return null!; + } + var status = _dbContext.Products.Remove(product!); + _dbContext.SaveChanges(); + + return status.ToString(); + } + + public async Task GetProductAsync(int id) + { + return await _dbContext.Products + .FirstOrDefaultAsync(product => product.Id == id); + } + + public async Task> GetProductListAsync(RequestPage request) + { + return _dbContext.Products.AsEnumerable() + .Where(x => x.Price == request.PriceMax || x.Name.Contains(request.Name)) + .Skip(request.PageSize * (request.PageNamber - 1)) + .Take(request.PageSize) + .OrderByDescending(x=>x.Name) + .ToList(); + } + } +} diff --git a/HomeWork22/HomeWork22/Services/Abstracts/BaseDataService.cs b/HomeWork22/HomeWork22/Services/Abstracts/BaseDataService.cs new file mode 100644 index 0000000..b0a5994 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/Abstracts/BaseDataService.cs @@ -0,0 +1,67 @@ +using HomeWork22.DbWrappers.Abstracts; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace HomeWork22.Services.Abstracts +{ + internal abstract class BaseDataService : IBaseDataService + where T : DbContext + { + private readonly IDbContextWrapper _dbContextWrapper; + private readonly ILogger _logger; + + public BaseDataService( + IDbContextWrapper dbContextWrapper, + ILogger logger) + { + _dbContextWrapper = dbContextWrapper; + _logger = logger; + } + + protected Task ExecuteSafeAsync(Func action, CancellationToken cancellationToken = default) => ExecuteSafeAsync(token => action(), cancellationToken); + + protected Task ExecuteSafeAsync(Func> action, CancellationToken cancellationToken = default) => ExecuteSafeAsync(token => action(), cancellationToken); + + private async Task ExecuteSafeAsync(Func action, CancellationToken cancellationToken = default) + { + await using var transaction = await _dbContextWrapper.BeginTrasactionAsync(cancellationToken); + + try + { + await action(cancellationToken); + + await transaction.CommitAsync(cancellationToken); + } + catch (Exception ex) + { + await transaction.RollbackAsync(cancellationToken); + + _logger.LogError(ex, $"transaction is roll back, some error"); + + throw; + } + } + + private async Task ExecuteSafeAsync(Func> action, CancellationToken cancellationToken = default) + { + await using var transaction = await _dbContextWrapper.BeginTrasactionAsync(cancellationToken); + + try + { + var result = await action(cancellationToken); + + await transaction.CommitAsync(cancellationToken); + + return result; + } + catch (Exception ex) + { + await transaction.RollbackAsync(cancellationToken); + + _logger.LogError(ex, $"Failed to execute, transaction is rollback"); + + throw; + } + } + } +} diff --git a/HomeWork22/HomeWork22/Services/Abstracts/IBaseDataService.cs b/HomeWork22/HomeWork22/Services/Abstracts/IBaseDataService.cs new file mode 100644 index 0000000..9a0fdc2 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/Abstracts/IBaseDataService.cs @@ -0,0 +1,6 @@ +namespace HomeWork22.Services.Abstracts +{ + internal interface IBaseDataService + { + } +} diff --git a/HomeWork22/HomeWork22/Services/Abstracts/ICostumerService.cs b/HomeWork22/HomeWork22/Services/Abstracts/ICostumerService.cs new file mode 100644 index 0000000..5680445 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/Abstracts/ICostumerService.cs @@ -0,0 +1,15 @@ +using HomeWork22.Models; + +namespace HomeWork22.Services.Abstracts +{ + internal interface ICostumerService + { + public Task AddCostumerAsync(string lastname, string firstname); + public Task GetCostumerAsync(int id); + public Task UpdateCostumerAsync( + int id, + string lastname = null!, + string firstname = null!); + public Task DeleteCostumerAsync(int id); + } +} diff --git a/HomeWork22/HomeWork22/Services/Abstracts/IOrderService.cs b/HomeWork22/HomeWork22/Services/Abstracts/IOrderService.cs new file mode 100644 index 0000000..2ac0926 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/Abstracts/IOrderService.cs @@ -0,0 +1,13 @@ +using HomeWork22.Models; + +namespace HomeWork22.Services.Abstracts +{ + internal interface IOrderService + { + public Task AddOrderAsync(int costumerId, List orderItems); + public Task GetOrderAsync(int id); + public Task> GetOrderByCostumerId(int id); + public Task DeleteOrderAsync(int id); + public Task UpdateOrderAsync(int id, List items); + } +} diff --git a/HomeWork22/HomeWork22/Services/Abstracts/IProductService.cs b/HomeWork22/HomeWork22/Services/Abstracts/IProductService.cs new file mode 100644 index 0000000..0f9d586 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/Abstracts/IProductService.cs @@ -0,0 +1,14 @@ +using HomeWork22.Dtos; +using HomeWork22.Models; + +namespace HomeWork22.Services.Abstracts +{ + internal interface IProductService + { + public Task AddProductAsync(string name, double price); + public Task GetProductAsync(int id); + public Task UpdataProductAsync(int id, string name = null!, double price = 0); + public Task DeleteProduct(int id); + public Task> GetViewProductListAsync(RequestPage request); + } +} diff --git a/HomeWork22/HomeWork22/Services/CostumerService.cs b/HomeWork22/HomeWork22/Services/CostumerService.cs new file mode 100644 index 0000000..5503e00 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/CostumerService.cs @@ -0,0 +1,85 @@ +using HomeWork22.Datas; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Models; +using HomeWork22.Repositories.Abstractions; +using HomeWork22.Services.Abstracts; +using Microsoft.Extensions.Logging; + +namespace HomeWork22.Services +{ + internal class CostumerService : BaseDataService, ICostumerService + { + private readonly ICostumerRepository _costumerRepository; + private readonly ILogger _logger; + + public CostumerService( + ICostumerRepository costumerRepository, + ILogger loggerService, + IDbContextWrapper dbContextWrapper, + ILogger> logger) + : base + (dbContextWrapper, logger) + { + _costumerRepository = costumerRepository; + _logger = loggerService; + } + + public async Task AddCostumerAsync(string lastname, string firstname) + { + return await ExecuteSafeAsync(async () => + { + var id = await _costumerRepository.AddCostumerAsync(lastname, firstname); + + _logger.LogInformation($"Succesfull create costumer with id: {id}"); + + return id; + }); + } + + public async Task UpdateCostumerAsync(int id, string lastname = null!, string firstname = null!) + { + return await ExecuteSafeAsync(async () => + { + var costumers = await _costumerRepository.UpdateCostumerAsync(id, lastname); + + return new Costumer() + { + Id = costumers.Id, + Lastname = costumers.LastName, + Firstname = costumers.FirstName, + Fullname = $"{costumers.LastName} {costumers.FirstName}" + }; + }); + } + + public async Task DeleteCostumerAsync(int id) + { + return await ExecuteSafeAsync(async () => + { + var status = await _costumerRepository.DeleteCostumerAsync(id); + + return status; + }); + } + + public async Task GetCostumerAsync(int id) + { + var costumerEntity = await _costumerRepository.GetCostumerAsync(id); + + if (costumerEntity is null) + { + _logger.LogWarning($"Costumer is not founded with id: {id}"); + + return null!; + } + + return new Costumer() + { + Id = costumerEntity.Id, + Firstname = costumerEntity.FirstName, + Lastname = costumerEntity.LastName, + Fullname = $"{costumerEntity.LastName} {costumerEntity.FirstName} ", + }; + } + } +} diff --git a/HomeWork22/HomeWork22/Services/OrderService.cs b/HomeWork22/HomeWork22/Services/OrderService.cs new file mode 100644 index 0000000..5e14ad5 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/OrderService.cs @@ -0,0 +1,185 @@ +using HomeWork22.Datas; +using HomeWork22.Datas.Entities; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Models; +using HomeWork22.Repositories.Abstractions; +using HomeWork22.Services.Abstracts; +using Microsoft.Extensions.Logging; + +namespace HomeWork22.Services +{ + internal class OrderService : BaseDataService, IOrderService + { + private readonly IOrderRepository _orderRepository; + private readonly ILogger _logger; + + public OrderService( + IOrderRepository orderRepository, + ILogger loggerService, + ILogger> logger, + IDbContextWrapper dbContextWrapper) + : base + (dbContextWrapper, logger) + { + _orderRepository = orderRepository; + _logger = loggerService; + } + + public async Task AddOrderAsync(int costumerId, List orderItems) + { + return await ExecuteSafeAsync(async () => + { + var orderItemEntity = new List(); + + orderItems.ForEach(s => + orderItemEntity.Add(new OrderItemEntity() + { + ProductId = s.ProductId, + Count = s.Count, + Product = new ProductEntity() + { + Id = s.Product.Id, + Price = s.Product.Price, + Name = s.Product.Name, + OrderItems = orderItemEntity + } + })); + + var id = await _orderRepository.AddOrderAsync(costumerId, orderItemEntity); + + _logger.LogInformation($"Order seccusfull created with id {id}"); + + return id; + }); + + } + + public async Task GetOrderAsync(int id) + { + return await ExecuteSafeAsync(async () => + { + var order = await _orderRepository.GetOrder(id); + + if (order is null) + { + _logger.LogWarning($"Order don`t finded with id {id}"); + + return null!; + } + + return new Order() + { + Id = order.Id, + + OrderItem = order.OrderItems.Select(s => new OrderItem() + { + Count = s.Count, + ProductId = s.ProductId, + + Product = new Product() + { + Id = s.Product.Id, + Name = s.Product.Name, + Price = s.Product.Price, + } + }) + }; + }); + } + + public async Task DeleteOrderAsync(int id) + { + return await ExecuteSafeAsync(async () => + { + var status = await _orderRepository.DeleteOrderAsync(id); + + if (status is null) + { + _logger.LogWarning($"Order don`t finded with id {id}"); + + return null!; + } + + _logger.LogInformation($"Order {id} is seccusfull delete"); + return status; + }); + } + + public async Task UpdateOrderAsync(int id, List items) + { + return await ExecuteSafeAsync(async () => + { + var entity = items.Select(s => new OrderItemEntity() + { + Count = s.Count, + ProductId = s.ProductId, + Product = new ProductEntity() + { + Id = s.Product.Id, + Name = s.Product.Name, + Price = s.Product.Price, + } + }).ToList(); + + var order = await _orderRepository.UpDataOrderAsync(id, entity); + if (order is null) + { + _logger.LogWarning($"Order don`t finded with id {id}"); + + return null!; + } + + _logger.LogInformation($"Update succesfull {order.Id}"); + + return new Order() + { + Id = order.Id, + Costumer = new Costumer() + { + Id = order.Costumer.Id, + Firstname = order.Costumer.FirstName, + Lastname = order.Costumer.LastName, + Fullname = $"{order.Costumer.FirstName} {order.Costumer.LastName}" + }, + OrderItem = new List().Select(s => new OrderItem() + { + Count = s.Count, + Product = s.Product, + ProductId = s.ProductId + }), + }; + }); + } + + public async Task> GetOrderByCostumerId(int id) + { + return await ExecuteSafeAsync(async () => + { + var order = await _orderRepository.GetOrderByCostumerId(id); + + if (order is null) + { + _logger.LogWarning($"Order not founded with id {id}"); + + return null!; + } + + return order.Select(s => new Order() + { + Id = s.Id, + OrderItem = s.OrderItems.Select(r => new OrderItem() + { + Count = r.Count, + ProductId = r.ProductId, + Product = new Product() + { + Id = r.Product.Id, + Name = r.Product.Name, + Price = r.Product.Price, + } + }) + }).ToList(); + }); + } + } +} diff --git a/HomeWork22/HomeWork22/Services/ProductService.cs b/HomeWork22/HomeWork22/Services/ProductService.cs new file mode 100644 index 0000000..d978d05 --- /dev/null +++ b/HomeWork22/HomeWork22/Services/ProductService.cs @@ -0,0 +1,122 @@ +using HomeWork22.Datas; +using HomeWork22.DbWrappers.Abstracts; +using HomeWork22.Dtos; +using HomeWork22.Models; +using HomeWork22.Repositories.Abstractions; +using HomeWork22.Services.Abstracts; +using Microsoft.Extensions.Logging; + +namespace HomeWork22.Services +{ + internal class ProductService : BaseDataService, IProductService + { + private readonly IProductRepository _productRepository; + private readonly ILogger _logger; + public ProductService( + IProductRepository productRepository, + ILogger loggerService, + ILogger> logger, + IDbContextWrapper dbContextWrapper) + : base + (dbContextWrapper, logger) + { + _productRepository = productRepository; + _logger = loggerService; + } + + public async Task AddProductAsync(string name, double price) + { + return await ExecuteSafeAsync(async () => + { + var id = await _productRepository.AddProductAsync(name, price); + + _logger.LogInformation($"Product succesfull create with id: {id}"); + + return id; + }); + } + + public async Task GetProductAsync(int id) + { + return await ExecuteSafeAsync(async () => + { + var product = await _productRepository.GetProductAsync(id); + + if (product is null) + { + _logger.LogWarning("Product with this id don`t exist"); + + return null!; + } + + return new Product() + { + Id = product.Id, + Name = product.Name, + Price = product.Price, + }; + }); + } + + public async Task DeleteProduct(int id) + { + return await ExecuteSafeAsync(async () => + { + var status = await _productRepository.DeleteProductAsync(id); + + if (status is null) + { + _logger.LogWarning($"product don`t finded with id {id}"); + + return null!; + } + _logger.LogInformation($"Product seccesfull deleted: {id}"); + + return status; + }); + } + + public async Task UpdataProductAsync(int id, string name = null!, double price = 0) + { + var product = await _productRepository.UpdataProductAsync(id, name, price); + if (product is null) + { + _logger.LogWarning("Product with this id don`t exist"); + + return null!; + } + + _logger.LogInformation($"Product with id: {id} seccusfull update"); + + return new Product() + { + Id = product.Id, + Name = product.Name, + Price = product.Price, + }; + } + + public async Task> GetViewProductListAsync(RequestPage request) + { + return await ExecuteSafeAsync(async () => + { + var product = await _productRepository.GetProductListAsync(request); + + if (product is null) + { + _logger.LogWarning("Product with this id don`t exist"); + + return null!; + } + + return product.Select(x => new Product() + { + Id = x.Id, + Name = x.Name, + Price = x.Price, + + }).ToList(); + }); + } + } +} diff --git a/HomeWork22/HomeWork22/Wrappers/Abstracts/IDbContextWrapper.cs b/HomeWork22/HomeWork22/Wrappers/Abstracts/IDbContextWrapper.cs new file mode 100644 index 0000000..9220d92 --- /dev/null +++ b/HomeWork22/HomeWork22/Wrappers/Abstracts/IDbContextWrapper.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; + +namespace HomeWork22.DbWrappers.Abstracts +{ + internal interface IDbContextWrapper where T : DbContext + { + public T DbContext { get; } + + public Task BeginTrasactionAsync(CancellationToken cancellationToken); + } +} diff --git a/HomeWork22/HomeWork22/Wrappers/DbContextWrapper.cs b/HomeWork22/HomeWork22/Wrappers/DbContextWrapper.cs new file mode 100644 index 0000000..91faa47 --- /dev/null +++ b/HomeWork22/HomeWork22/Wrappers/DbContextWrapper.cs @@ -0,0 +1,24 @@ +using HomeWork22.DbWrappers.Abstracts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; + +namespace HomeWork22.DbWrappers +{ + internal class DbContextWrapper : IDbContextWrapper + where T : DbContext + { + private readonly T _dbContext; + + public DbContextWrapper(IDbContextFactory dbContextFactory) + { + _dbContext = dbContextFactory.CreateDbContext(); + } + + public T DbContext => _dbContext; + + public Task BeginTrasactionAsync(CancellationToken cancellationToken) + { + return _dbContext.Database.BeginTransactionAsync(cancellationToken); + } + } +} diff --git a/HomeWork22/HomeWork22/config.json b/HomeWork22/HomeWork22/config.json new file mode 100644 index 0000000..e2c10b5 --- /dev/null +++ b/HomeWork22/HomeWork22/config.json @@ -0,0 +1,9 @@ +{ + "Migration": { + "IsNeedMigration": true + }, + "ConnectionStrings": { + "DefaultConnection": "Server=127.0.0.1,1434;Database=AdventureWorks;User ID=sa;Password=1My_password;TrustServerCertificate=true" + } + +} \ No newline at end of file