From 3576b2cbb3fbf7142c5e28501a399f713b60fee0 Mon Sep 17 00:00:00 2001 From: Axel Ahlander Date: Mon, 27 Jan 2025 14:06:03 +0100 Subject: [PATCH 1/3] core + started extension --- exercise.pizzashopapi/DTO/CustomerDTO.cs | 9 + exercise.pizzashopapi/DTO/OrderDTO.cs | 10 + exercise.pizzashopapi/DTO/OrderToppingsDTO.cs | 8 + exercise.pizzashopapi/DTO/PizzaDTO.cs | 9 + exercise.pizzashopapi/DTO/ToppingsDTO.cs | 9 + exercise.pizzashopapi/Data/DataContext.cs | 36 ++++ exercise.pizzashopapi/Data/Seeder.cs | 97 +++++++++- .../EndPoints/PizzaShopApi.cs | 66 ++++++- .../20250127122917_first.Designer.cs | 177 ++++++++++++++++++ .../Migrations/20250127122917_first.cs | 140 ++++++++++++++ .../Migrations/DataContextModelSnapshot.cs | 174 +++++++++++++++++ exercise.pizzashopapi/Models/Customer.cs | 1 + exercise.pizzashopapi/Models/Order.cs | 8 + exercise.pizzashopapi/Models/OrderToppings.cs | 11 ++ exercise.pizzashopapi/Models/Pizza.cs | 1 + exercise.pizzashopapi/Models/Toppings.cs | 10 + .../Repository/IRepository.cs | 6 +- .../Repository/Repository.cs | 33 +++- 18 files changed, 794 insertions(+), 11 deletions(-) create mode 100644 exercise.pizzashopapi/DTO/CustomerDTO.cs create mode 100644 exercise.pizzashopapi/DTO/OrderDTO.cs create mode 100644 exercise.pizzashopapi/DTO/OrderToppingsDTO.cs create mode 100644 exercise.pizzashopapi/DTO/PizzaDTO.cs create mode 100644 exercise.pizzashopapi/DTO/ToppingsDTO.cs create mode 100644 exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs create mode 100644 exercise.pizzashopapi/Migrations/20250127122917_first.cs create mode 100644 exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs create mode 100644 exercise.pizzashopapi/Models/OrderToppings.cs create mode 100644 exercise.pizzashopapi/Models/Toppings.cs diff --git a/exercise.pizzashopapi/DTO/CustomerDTO.cs b/exercise.pizzashopapi/DTO/CustomerDTO.cs new file mode 100644 index 0000000..c93c5b1 --- /dev/null +++ b/exercise.pizzashopapi/DTO/CustomerDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class CustomerDTO + { + public int Id { get; set; } + public string Name { get; set; } + public List Orders { get; set; } = new List(); + } +} diff --git a/exercise.pizzashopapi/DTO/OrderDTO.cs b/exercise.pizzashopapi/DTO/OrderDTO.cs new file mode 100644 index 0000000..814c01c --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderDTO.cs @@ -0,0 +1,10 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderDTO + { + public int Id { get; set; } + public int PizzaId { get; set; } + public int CustomerId { get; set; } + public List OrderToppingsDTOs { get; set; } = new List(); + } +} diff --git a/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs b/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs new file mode 100644 index 0000000..96db120 --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderToppingsDTO.cs @@ -0,0 +1,8 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderToppingsDTO + { + public int orderId { get; set; } + public int toppingId { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/PizzaDTO.cs b/exercise.pizzashopapi/DTO/PizzaDTO.cs new file mode 100644 index 0000000..8991446 --- /dev/null +++ b/exercise.pizzashopapi/DTO/PizzaDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class PizzaDTO + { + public int Id { get; set; } + public int price { get; set; } + public string name { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/ToppingsDTO.cs b/exercise.pizzashopapi/DTO/ToppingsDTO.cs new file mode 100644 index 0000000..b1a74ee --- /dev/null +++ b/exercise.pizzashopapi/DTO/ToppingsDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class ToppingsDTO + { + public int Id; + public string name; + public int cost; + } +} diff --git a/exercise.pizzashopapi/Data/DataContext.cs b/exercise.pizzashopapi/Data/DataContext.cs index 129199e..19cfb21 100644 --- a/exercise.pizzashopapi/Data/DataContext.cs +++ b/exercise.pizzashopapi/Data/DataContext.cs @@ -16,13 +16,49 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql(connectionString); + //set primary of order? //seed data? + + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasKey(x => x.orderId); + modelBuilder.Entity() + .HasMany(c => c.Orders) + .WithOne(o => o.Customer) + .HasForeignKey(o => o.customerId); + + modelBuilder.Entity() + .HasOne(x => x.Pizza) + .WithMany() + .HasForeignKey(x => x.pizzaId); + + modelBuilder.Entity() + .HasKey(ot => new { ot.OrderId, ot.ToppingId }); + + modelBuilder.Entity() + .HasOne(ot => ot.Order) + .WithMany(o => o.toppings) + .HasForeignKey(ot => ot.OrderId); + + modelBuilder.Entity() + .HasOne(ot => ot.Topping) + .WithMany(t => t.OrderToppings) + .HasForeignKey(ot => ot.ToppingId); + } + + + + public DbSet Pizzas { get; set; } public DbSet Customers { get; set; } public DbSet Orders { get; set; } + public DbSet Toppings { get; set; } + public DbSet OrderToppings { get; set; } } } diff --git a/exercise.pizzashopapi/Data/Seeder.cs b/exercise.pizzashopapi/Data/Seeder.cs index f87fbef..ed20c6c 100644 --- a/exercise.pizzashopapi/Data/Seeder.cs +++ b/exercise.pizzashopapi/Data/Seeder.cs @@ -10,24 +10,111 @@ public async static void SeedPizzaShopApi(this WebApplication app) { if(!db.Customers.Any()) { - db.Add(new Customer() { Name="Nigel" }); - db.Add(new Customer() { Name = "Dave" }); + db.Add(new Customer() { Id = 1, Name="Nigel" }); + db.Add(new Customer() { Id = 2, Name = "Dave" }); + db.Add(new Customer() { Id = 3, Name = "Axel" }); await db.SaveChangesAsync(); } if(!db.Pizzas.Any()) { - db.Add(new Pizza() { Name = "Cheese & Pineapple" }); - db.Add(new Pizza() { Name = "Vegan Cheese Tastic" }); + db.Add(new Pizza() + { + Id = 1, + Name = "Cheese & Pineapple", + Price = 10, + + }); + db.Add(new Pizza() { Id = 2, Name = "Vegan Cheese Tastic" , Price = 20 }); + db.Add(new Pizza() { Id = 3, Name = "Kebab Pizza", Price = 15 }); await db.SaveChangesAsync(); } + if (!db.Toppings.Any()) + { + db.Add(new Toppings() + { + name = "meat", + id = 1, + cost = 4 + }); + + db.Add(new Toppings() + { + name = "gold", + id = 2, + cost = 40 + }); + + db.Add(new Toppings() + { + name = "truffle", + id = 3, + cost = 15 + }); + + + } + //order data - if(1==1) + if (!db.Orders.Any()) { + db.Add(new Order() + { + pizzaId = 1, + customerId = 2, + orderId = 1, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 2 + } + } + }); + + db.Add(new Order() + { + pizzaId = 3, + customerId = 3, + orderId = 2, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 3 + } + } + }); + + db.Add(new Order() + { + pizzaId = 2, + customerId = 1, + orderId = 3, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 2 + } + } + }); + await db.SaveChangesAsync(); } + + } } } diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs index f8be2b0..d0dcb9e 100644 --- a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs +++ b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs @@ -1,4 +1,6 @@ -using exercise.pizzashopapi.Repository; +using exercise.pizzashopapi.DTO; +using exercise.pizzashopapi.Models; +using exercise.pizzashopapi.Repository; using Microsoft.AspNetCore.Mvc; namespace exercise.pizzashopapi.EndPoints @@ -7,9 +9,69 @@ public static class PizzaShopApi { public static void ConfigurePizzaShopApi(this WebApplication app) { + var restaurant = app.MapGroup("/restaurant"); + restaurant.MapGet("/pizzas", GetPizzas); + restaurant.MapGet("/customers", GetCustomers); + } + + public static async Task GetPizzas(IRepository repo) + { + IEnumerablepizzas = await repo.GetPizzas(); + return TypedResults.Ok(pizzas); + } + + public static async Task GetCustomers(IRepository repo) + { + + ListDTOList = new List (); + + foreach (Customer customer in await repo.GetCustomers()) { + CustomerDTO dto = new CustomerDTO(); + dto.Name = customer.Name; + dto.Id = customer.Id; + foreach(Order order in await repo.GetOrdersByCustomer(customer.Id)) + { + OrderDTO orderDTO = new OrderDTO(); + orderDTO.Id = order.orderId; + orderDTO.CustomerId = order.customerId; + orderDTO.PizzaId = order.pizzaId; + orderDTO.OrderToppingsDTOs = new List(); + if (order.toppings != null) + { + foreach (OrderToppings toppings in order.toppings.ToList()) + { + OrderToppingsDTO OTD = new OrderToppingsDTO(); + OTD.orderId = order.orderId; + OTD.toppingId = toppings.ToppingId; + orderDTO.OrderToppingsDTOs.Add(OTD); + } + } + + + + + dto.Orders.Add(orderDTO); + } + DTOList.Add(dto); + + } + + + + return TypedResults.Ok(DTOList); + } + public static async Task GetOrders(IRepository repo) + { + IEnumerable orders = await repo.GetOrders(); + return TypedResults.Ok(orders); + } + + public static async Task GetOrderByCustomer(IRepository repo, int id) + { + IEnumerable orders = await repo.GetOrdersByCustomer(id); + return TypedResults.Ok(orders); } - } } diff --git a/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs b/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs new file mode 100644 index 0000000..d59d9ec --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs @@ -0,0 +1,177 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using exercise.pizzashopapi.Data; + +#nullable disable + +namespace exercise.pizzashopapi.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250127122917_first")] + partial class first + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Customers"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("orderId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("orderId")); + + b.Property("customerId") + .HasColumnType("integer"); + + b.Property("pizzaId") + .HasColumnType("integer"); + + b.HasKey("orderId"); + + b.HasIndex("customerId"); + + b.HasIndex("pizzaId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => + { + b.Property("OrderId") + .HasColumnType("integer"); + + b.Property("ToppingId") + .HasColumnType("integer"); + + b.HasKey("OrderId", "ToppingId"); + + b.HasIndex("ToppingId"); + + b.ToTable("OrderToppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.ToTable("Pizzas"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("id")); + + b.Property("cost") + .HasColumnType("integer"); + + b.Property("name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("id"); + + b.ToTable("Toppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.HasOne("exercise.pizzashopapi.Models.Customer", "Customer") + .WithMany("Orders") + .HasForeignKey("customerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("exercise.pizzashopapi.Models.Pizza", "Pizza") + .WithMany() + .HasForeignKey("pizzaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Pizza"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => + { + b.HasOne("exercise.pizzashopapi.Models.Order", "Order") + .WithMany("toppings") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("exercise.pizzashopapi.Models.Toppings", "Topping") + .WithMany("OrderToppings") + .HasForeignKey("ToppingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Topping"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Navigation("toppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => + { + b.Navigation("OrderToppings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/exercise.pizzashopapi/Migrations/20250127122917_first.cs b/exercise.pizzashopapi/Migrations/20250127122917_first.cs new file mode 100644 index 0000000..65c4494 --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250127122917_first.cs @@ -0,0 +1,140 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace exercise.pizzashopapi.Migrations +{ + /// + public partial class first : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Customers", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Customers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Pizzas", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false), + Price = table.Column(type: "numeric", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Pizzas", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Toppings", + columns: table => new + { + id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + name = table.Column(type: "text", nullable: false), + cost = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Toppings", x => x.id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + orderId = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + customerId = table.Column(type: "integer", nullable: false), + pizzaId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.orderId); + table.ForeignKey( + name: "FK_Orders_Customers_customerId", + column: x => x.customerId, + principalTable: "Customers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Pizzas_pizzaId", + column: x => x.pizzaId, + principalTable: "Pizzas", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderToppings", + columns: table => new + { + OrderId = table.Column(type: "integer", nullable: false), + ToppingId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderToppings", x => new { x.OrderId, x.ToppingId }); + table.ForeignKey( + name: "FK_OrderToppings_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "orderId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_OrderToppings_Toppings_ToppingId", + column: x => x.ToppingId, + principalTable: "Toppings", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Orders_customerId", + table: "Orders", + column: "customerId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_pizzaId", + table: "Orders", + column: "pizzaId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderToppings_ToppingId", + table: "OrderToppings", + column: "ToppingId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "OrderToppings"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Toppings"); + + migrationBuilder.DropTable( + name: "Customers"); + + migrationBuilder.DropTable( + name: "Pizzas"); + } + } +} diff --git a/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs new file mode 100644 index 0000000..1c44544 --- /dev/null +++ b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs @@ -0,0 +1,174 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using exercise.pizzashopapi.Data; + +#nullable disable + +namespace exercise.pizzashopapi.Migrations +{ + [DbContext(typeof(DataContext))] + partial class DataContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Customers"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("orderId") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("orderId")); + + b.Property("customerId") + .HasColumnType("integer"); + + b.Property("pizzaId") + .HasColumnType("integer"); + + b.HasKey("orderId"); + + b.HasIndex("customerId"); + + b.HasIndex("pizzaId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => + { + b.Property("OrderId") + .HasColumnType("integer"); + + b.Property("ToppingId") + .HasColumnType("integer"); + + b.HasKey("OrderId", "ToppingId"); + + b.HasIndex("ToppingId"); + + b.ToTable("OrderToppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.ToTable("Pizzas"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => + { + b.Property("id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("id")); + + b.Property("cost") + .HasColumnType("integer"); + + b.Property("name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("id"); + + b.ToTable("Toppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.HasOne("exercise.pizzashopapi.Models.Customer", "Customer") + .WithMany("Orders") + .HasForeignKey("customerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("exercise.pizzashopapi.Models.Pizza", "Pizza") + .WithMany() + .HasForeignKey("pizzaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Pizza"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => + { + b.HasOne("exercise.pizzashopapi.Models.Order", "Order") + .WithMany("toppings") + .HasForeignKey("OrderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("exercise.pizzashopapi.Models.Toppings", "Topping") + .WithMany("OrderToppings") + .HasForeignKey("ToppingId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Order"); + + b.Navigation("Topping"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Navigation("toppings"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => + { + b.Navigation("OrderToppings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/exercise.pizzashopapi/Models/Customer.cs b/exercise.pizzashopapi/Models/Customer.cs index 2ca83bd..63c87bf 100644 --- a/exercise.pizzashopapi/Models/Customer.cs +++ b/exercise.pizzashopapi/Models/Customer.cs @@ -6,5 +6,6 @@ public class Customer { public int Id { get; set; } public string Name { get; set; } + public List Orders { get; set; } } } diff --git a/exercise.pizzashopapi/Models/Order.cs b/exercise.pizzashopapi/Models/Order.cs index fbe6113..a4812b8 100644 --- a/exercise.pizzashopapi/Models/Order.cs +++ b/exercise.pizzashopapi/Models/Order.cs @@ -4,7 +4,15 @@ namespace exercise.pizzashopapi.Models { public class Order { + public int orderId { get; set; } + public int customerId { get; set; } + public int pizzaId { get; set; } + + public List toppings { get; set; } + public Customer Customer { get; set; } + + public Pizza Pizza { get; set; } } } diff --git a/exercise.pizzashopapi/Models/OrderToppings.cs b/exercise.pizzashopapi/Models/OrderToppings.cs new file mode 100644 index 0000000..f7f45f1 --- /dev/null +++ b/exercise.pizzashopapi/Models/OrderToppings.cs @@ -0,0 +1,11 @@ +namespace exercise.pizzashopapi.Models +{ + public class OrderToppings + { + public int OrderId { get; set; } + public Order Order { get; set; } + + public int ToppingId { get; set; } + public Toppings Topping { get; set; } + } +} diff --git a/exercise.pizzashopapi/Models/Pizza.cs b/exercise.pizzashopapi/Models/Pizza.cs index 5c085ec..649b610 100644 --- a/exercise.pizzashopapi/Models/Pizza.cs +++ b/exercise.pizzashopapi/Models/Pizza.cs @@ -8,5 +8,6 @@ public class Pizza public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } + } } \ No newline at end of file diff --git a/exercise.pizzashopapi/Models/Toppings.cs b/exercise.pizzashopapi/Models/Toppings.cs new file mode 100644 index 0000000..51e2c0d --- /dev/null +++ b/exercise.pizzashopapi/Models/Toppings.cs @@ -0,0 +1,10 @@ +namespace exercise.pizzashopapi.Models +{ + public class Toppings + { + public int id { get; set; } + public string name { get; set; } + public int cost {get;set;} + public List OrderToppings { get; set; } + } +} diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index b114ea8..f06286b 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -5,7 +5,9 @@ namespace exercise.pizzashopapi.Repository public interface IRepository { Task> GetOrdersByCustomer(int id); - - + Task> GetPizzas(); + Task> GetCustomers(); + Task> GetOrders(); + TaskGetOrderById(int id); } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index e109fce..0f20711 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -1,14 +1,43 @@ using exercise.pizzashopapi.Data; using exercise.pizzashopapi.Models; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Repository { public class Repository : IRepository { private DataContext _db; - public Task> GetOrdersByCustomer(int id) + + public Repository(DataContext db) + { + _db = db; + } + + public async Task> GetOrdersByCustomer(int id) + { + IEnumerableorders = await _db.Orders.Where(x => x.customerId == id).Include(o => o.toppings).ToListAsync(); + return orders; + } + + public async Task> GetPizzas() + { + return await _db.Pizzas.ToListAsync(); + } + + public async Task> GetCustomers() + { + var customers = await _db.Customers.Include(c => c.Orders).ToListAsync(); + return customers; + } + + public async Task> GetOrders() + { + return await _db.Orders.ToListAsync(); + } + + public async Task GetOrderById(int id) { - throw new NotImplementedException(); + return _db.Orders.Where(x => x.orderId == id).FirstOrDefault()!; } } } From a7cf7f9e047b3b3c031a26cb382a775355c33072 Mon Sep 17 00:00:00 2001 From: Axel Ahlander Date: Mon, 27 Jan 2025 15:44:11 +0100 Subject: [PATCH 2/3] toppings included --- exercise.pizzashopapi/DTO/CustomerDTO.cs | 2 +- exercise.pizzashopapi/DTO/OTDTO.cs | 8 ++++ exercise.pizzashopapi/DTO/OrderDTO.cs | 2 +- .../DTO/OrderSimplifiedDTO.cs | 9 ++++ exercise.pizzashopapi/DTO/ToppingsDTO.cs | 6 +-- .../EndPoints/PizzaShopApi.cs | 41 ++++++++++--------- .../Repository/IRepository.cs | 2 + .../Repository/Repository.cs | 28 +++++++++++++ 8 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 exercise.pizzashopapi/DTO/OTDTO.cs create mode 100644 exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs diff --git a/exercise.pizzashopapi/DTO/CustomerDTO.cs b/exercise.pizzashopapi/DTO/CustomerDTO.cs index c93c5b1..f76cd21 100644 --- a/exercise.pizzashopapi/DTO/CustomerDTO.cs +++ b/exercise.pizzashopapi/DTO/CustomerDTO.cs @@ -4,6 +4,6 @@ public class CustomerDTO { public int Id { get; set; } public string Name { get; set; } - public List Orders { get; set; } = new List(); + public List Orders { get; set; } = new List(); } } diff --git a/exercise.pizzashopapi/DTO/OTDTO.cs b/exercise.pizzashopapi/DTO/OTDTO.cs new file mode 100644 index 0000000..800fe5c --- /dev/null +++ b/exercise.pizzashopapi/DTO/OTDTO.cs @@ -0,0 +1,8 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OTDTO + { + public string name { get; set; } + + } +} diff --git a/exercise.pizzashopapi/DTO/OrderDTO.cs b/exercise.pizzashopapi/DTO/OrderDTO.cs index 814c01c..f1224a0 100644 --- a/exercise.pizzashopapi/DTO/OrderDTO.cs +++ b/exercise.pizzashopapi/DTO/OrderDTO.cs @@ -5,6 +5,6 @@ public class OrderDTO public int Id { get; set; } public int PizzaId { get; set; } public int CustomerId { get; set; } - public List OrderToppingsDTOs { get; set; } = new List(); + public List OrderToppingsDTOs { get; set; } = new List(); } } diff --git a/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs new file mode 100644 index 0000000..d076e6b --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs @@ -0,0 +1,9 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderSimplifiedDTO + { + public string pizzaname { get; set; } + + public Listpizzatoppings { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/ToppingsDTO.cs b/exercise.pizzashopapi/DTO/ToppingsDTO.cs index b1a74ee..0b84346 100644 --- a/exercise.pizzashopapi/DTO/ToppingsDTO.cs +++ b/exercise.pizzashopapi/DTO/ToppingsDTO.cs @@ -2,8 +2,8 @@ { public class ToppingsDTO { - public int Id; - public string name; - public int cost; + public int Id { get; set; } + public string name { get; set; } + public int cost { get; set; } } } diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs index d0dcb9e..d3b9437 100644 --- a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs +++ b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs @@ -24,38 +24,39 @@ public static async Task GetCustomers(IRepository repo) { ListDTOList = new List (); - - foreach (Customer customer in await repo.GetCustomers()) { + + foreach (Customer customer in await repo.GetCustomers()) + { CustomerDTO dto = new CustomerDTO(); dto.Name = customer.Name; dto.Id = customer.Id; - foreach(Order order in await repo.GetOrdersByCustomer(customer.Id)) + foreach (Order order in await repo.GetOrdersByCustomer(customer.Id)) { - OrderDTO orderDTO = new OrderDTO(); - orderDTO.Id = order.orderId; - orderDTO.CustomerId = order.customerId; - orderDTO.PizzaId = order.pizzaId; - orderDTO.OrderToppingsDTOs = new List(); + OrderSimplifiedDTO orderDTO = new OrderSimplifiedDTO(); + Pizza pizza = await repo.GetPizzaById(order.pizzaId); + + orderDTO.pizzaname = pizza.Name; + orderDTO.pizzatoppings = new List(); + if (order.toppings != null) { foreach (OrderToppings toppings in order.toppings.ToList()) { - OrderToppingsDTO OTD = new OrderToppingsDTO(); - OTD.orderId = order.orderId; - OTD.toppingId = toppings.ToppingId; - orderDTO.OrderToppingsDTOs.Add(OTD); + Toppings top = await repo.GetToppingsById(toppings.ToppingId); + OTDTO OTD = new OTDTO(); + OTD.name = top.name; + orderDTO.pizzatoppings.Add(OTD); } - } - - - - + + + + dto.Orders.Add(orderDTO); } - DTOList.Add(dto); - - } + } + DTOList.Add(dto); + } diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index f06286b..8427ede 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -9,5 +9,7 @@ public interface IRepository Task> GetCustomers(); Task> GetOrders(); TaskGetOrderById(int id); + Task GetPizzaById(int id); + Task GetToppingsById(int id); } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index 0f20711..827c88c 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -39,5 +39,33 @@ public async Task GetOrderById(int id) { return _db.Orders.Where(x => x.orderId == id).FirstOrDefault()!; } + + public async TaskAddTopping(Toppings topping) + { + _db.Toppings.Add(topping); + _db.SaveChanges(); + return topping; + } + + public async TaskAddToppingToOrder(Toppings topping, OrderToppings top) + { + top.Topping = topping; + top.ToppingId = topping.id; + _db.Toppings.Add(topping); + _db.OrderToppings.Add(top); + _db.SaveChanges(); + + return top; + } + + public async Task GetPizzaById(int id) + { + return _db.Pizzas.Where(x => x.Id == id).FirstOrDefault()!; + } + + public async Task GetToppingsById(int id) + { + return _db.Toppings.Where(x => x.id == id).FirstOrDefault(); + } } } From 82eb546457bc6b1a7e9240f015526f8ede1d443d Mon Sep 17 00:00:00 2001 From: Axel Ahlander Date: Wed, 29 Jan 2025 09:52:41 +0100 Subject: [PATCH 3/3] allowed multiple products such as burger --- README.md | 2 +- exercise.pizzashopapi/DTO/OrderDTO.cs | 10 - .../DTO/OrderSimplifiedDTO.cs | 5 +- .../DTO/{PizzaDTO.cs => ProductDTO.cs} | 2 +- exercise.pizzashopapi/Data/DataContext.cs | 12 +- exercise.pizzashopapi/Data/Seeder.cs | 44 ++++- .../{PizzaShopApi.cs => ProductShopApi.cs} | 21 ++- .../20250127122917_first.Designer.cs | 177 ------------------ .../Migrations/20250127122917_first.cs | 140 -------------- .../Migrations/DataContextModelSnapshot.cs | 174 ----------------- exercise.pizzashopapi/Models/Order.cs | 4 +- .../Models/{Pizza.cs => Product.cs} | 3 +- exercise.pizzashopapi/Program.cs | 4 +- .../Repository/IRepository.cs | 4 +- .../Repository/Repository.cs | 8 +- 15 files changed, 68 insertions(+), 542 deletions(-) delete mode 100644 exercise.pizzashopapi/DTO/OrderDTO.cs rename exercise.pizzashopapi/DTO/{PizzaDTO.cs => ProductDTO.cs} (85%) rename exercise.pizzashopapi/EndPoints/{PizzaShopApi.cs => ProductShopApi.cs} (74%) delete mode 100644 exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs delete mode 100644 exercise.pizzashopapi/Migrations/20250127122917_first.cs delete mode 100644 exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs rename exercise.pizzashopapi/Models/{Pizza.cs => Product.cs} (78%) diff --git a/README.md b/README.md index 714679a..3f1f0bf 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Pizza Shop needs a very simple ordering system with just just 3 tables, Customer - Write all endpoints in the PizzaShopApi.cs - Use your initiative to create relevant endpoints such as GetOrders, GetOrdersByCustomerId, GetPizzas etc.. -- Use Dependency Injection to instance the DbContext Repository +- Use Dependency Injection to instance the DbContext Retoppository - Inject the IRepository into the EndPoints in the PizzaShopApi - An order consists of 1 customer ordering 1 pizza. - Seed some data for the orders. Dave likes a Cheese & Pineapple pizza and Nigel likes Vegan ones. diff --git a/exercise.pizzashopapi/DTO/OrderDTO.cs b/exercise.pizzashopapi/DTO/OrderDTO.cs deleted file mode 100644 index f1224a0..0000000 --- a/exercise.pizzashopapi/DTO/OrderDTO.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace exercise.pizzashopapi.DTO -{ - public class OrderDTO - { - public int Id { get; set; } - public int PizzaId { get; set; } - public int CustomerId { get; set; } - public List OrderToppingsDTOs { get; set; } = new List(); - } -} diff --git a/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs index d076e6b..fa1542b 100644 --- a/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs +++ b/exercise.pizzashopapi/DTO/OrderSimplifiedDTO.cs @@ -2,8 +2,9 @@ { public class OrderSimplifiedDTO { - public string pizzaname { get; set; } + public string productname { get; set; } + public string productType { get; set; } - public Listpizzatoppings { get; set; } + public Listproducttoppings { get; set; } } } diff --git a/exercise.pizzashopapi/DTO/PizzaDTO.cs b/exercise.pizzashopapi/DTO/ProductDTO.cs similarity index 85% rename from exercise.pizzashopapi/DTO/PizzaDTO.cs rename to exercise.pizzashopapi/DTO/ProductDTO.cs index 8991446..47b2ea3 100644 --- a/exercise.pizzashopapi/DTO/PizzaDTO.cs +++ b/exercise.pizzashopapi/DTO/ProductDTO.cs @@ -1,6 +1,6 @@ namespace exercise.pizzashopapi.DTO { - public class PizzaDTO + public class ProductDTO { public int Id { get; set; } public int price { get; set; } diff --git a/exercise.pizzashopapi/Data/DataContext.cs b/exercise.pizzashopapi/Data/DataContext.cs index 19cfb21..3cf8e3c 100644 --- a/exercise.pizzashopapi/Data/DataContext.cs +++ b/exercise.pizzashopapi/Data/DataContext.cs @@ -29,14 +29,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasKey(x => x.orderId); modelBuilder.Entity() - .HasMany(c => c.Orders) - .WithOne(o => o.Customer) - .HasForeignKey(o => o.customerId); + .HasMany(c => c.Orders) + .WithOne(o => o.Customer). + HasForeignKey(o => o.customerId); modelBuilder.Entity() - .HasOne(x => x.Pizza) + .HasOne(x => x.Product) .WithMany() - .HasForeignKey(x => x.pizzaId); + .HasForeignKey(x => x.productId); modelBuilder.Entity() .HasKey(ot => new { ot.OrderId, ot.ToppingId }); @@ -55,7 +55,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) - public DbSet Pizzas { get; set; } + public DbSet Products { get; set; } public DbSet Customers { get; set; } public DbSet Orders { get; set; } public DbSet Toppings { get; set; } diff --git a/exercise.pizzashopapi/Data/Seeder.cs b/exercise.pizzashopapi/Data/Seeder.cs index ed20c6c..ba5b01e 100644 --- a/exercise.pizzashopapi/Data/Seeder.cs +++ b/exercise.pizzashopapi/Data/Seeder.cs @@ -4,7 +4,7 @@ namespace exercise.pizzashopapi.Data { public static class Seeder { - public async static void SeedPizzaShopApi(this WebApplication app) + public async static void SeedProductShopApi(this WebApplication app) { using(var db = new DataContext()) { @@ -15,17 +15,19 @@ public async static void SeedPizzaShopApi(this WebApplication app) db.Add(new Customer() { Id = 3, Name = "Axel" }); await db.SaveChangesAsync(); } - if(!db.Pizzas.Any()) + if(!db.Products.Any()) { - db.Add(new Pizza() + db.Add(new Product() { Id = 1, + Type = "Pizza", Name = "Cheese & Pineapple", Price = 10, }); - db.Add(new Pizza() { Id = 2, Name = "Vegan Cheese Tastic" , Price = 20 }); - db.Add(new Pizza() { Id = 3, Name = "Kebab Pizza", Price = 15 }); + db.Add(new Product() { Id = 2, Type = "Pizza", Name = "Vegan Cheese Tastic" , Price = 20 }); + db.Add(new Product() { Id = 3, Type = "Pizza", Name = "Kebab Pizza", Price = 15 }); + db.Add(new Product() { Id = 4, Type = "Burger", Name = "Whopper Cheese", Price=15 }); await db.SaveChangesAsync(); } @@ -52,6 +54,12 @@ public async static void SeedPizzaShopApi(this WebApplication app) id = 3, cost = 15 }); + db.Add(new Toppings() + { + name = "BBQ sauce", + id = 4, + cost = 2 + }); } @@ -61,7 +69,7 @@ public async static void SeedPizzaShopApi(this WebApplication app) { db.Add(new Order() { - pizzaId = 1, + productId = 1, customerId = 2, orderId = 1, toppings = new List(){ @@ -78,7 +86,7 @@ public async static void SeedPizzaShopApi(this WebApplication app) db.Add(new Order() { - pizzaId = 3, + productId = 3, customerId = 3, orderId = 2, toppings = new List(){ @@ -95,20 +103,36 @@ public async static void SeedPizzaShopApi(this WebApplication app) db.Add(new Order() { - pizzaId = 2, + productId = 2, customerId = 1, orderId = 3, toppings = new List(){ new OrderToppings() { - + ToppingId = 1 }, new OrderToppings() { - + ToppingId = 2 } } }); + db.Add(new Order() + { + productId = 4, + customerId = 1, + orderId = 4, + toppings = new List(){ + new OrderToppings() { + + ToppingId = 1 + }, + new OrderToppings() { + + ToppingId = 4 + } + } + }); await db.SaveChangesAsync(); diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/ProductShopApi.cs similarity index 74% rename from exercise.pizzashopapi/EndPoints/PizzaShopApi.cs rename to exercise.pizzashopapi/EndPoints/ProductShopApi.cs index d3b9437..a7a1502 100644 --- a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs +++ b/exercise.pizzashopapi/EndPoints/ProductShopApi.cs @@ -5,19 +5,19 @@ namespace exercise.pizzashopapi.EndPoints { - public static class PizzaShopApi + public static class ProductShopApi { - public static void ConfigurePizzaShopApi(this WebApplication app) + public static void ConfigureProductShopApi(this WebApplication app) { var restaurant = app.MapGroup("/restaurant"); - restaurant.MapGet("/pizzas", GetPizzas); + restaurant.MapGet("/products", GetProducts); restaurant.MapGet("/customers", GetCustomers); } - public static async Task GetPizzas(IRepository repo) + public static async Task GetProducts(IRepository repo) { - IEnumerablepizzas = await repo.GetPizzas(); - return TypedResults.Ok(pizzas); + IEnumerableproducts = await repo.GetProducts(); + return TypedResults.Ok(products); } public static async Task GetCustomers(IRepository repo) @@ -33,10 +33,11 @@ public static async Task GetCustomers(IRepository repo) foreach (Order order in await repo.GetOrdersByCustomer(customer.Id)) { OrderSimplifiedDTO orderDTO = new OrderSimplifiedDTO(); - Pizza pizza = await repo.GetPizzaById(order.pizzaId); + Product product = await repo.GetProductById(order.productId); - orderDTO.pizzaname = pizza.Name; - orderDTO.pizzatoppings = new List(); + orderDTO.productname = product.Name; + orderDTO.productType = product.Type; + orderDTO.producttoppings = new List(); if (order.toppings != null) { @@ -45,7 +46,7 @@ public static async Task GetCustomers(IRepository repo) Toppings top = await repo.GetToppingsById(toppings.ToppingId); OTDTO OTD = new OTDTO(); OTD.name = top.name; - orderDTO.pizzatoppings.Add(OTD); + orderDTO.producttoppings.Add(OTD); } diff --git a/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs b/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs deleted file mode 100644 index d59d9ec..0000000 --- a/exercise.pizzashopapi/Migrations/20250127122917_first.Designer.cs +++ /dev/null @@ -1,177 +0,0 @@ -// -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using exercise.pizzashopapi.Data; - -#nullable disable - -namespace exercise.pizzashopapi.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20250127122917_first")] - partial class first - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "7.0.11") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Customers"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.Property("orderId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("orderId")); - - b.Property("customerId") - .HasColumnType("integer"); - - b.Property("pizzaId") - .HasColumnType("integer"); - - b.HasKey("orderId"); - - b.HasIndex("customerId"); - - b.HasIndex("pizzaId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => - { - b.Property("OrderId") - .HasColumnType("integer"); - - b.Property("ToppingId") - .HasColumnType("integer"); - - b.HasKey("OrderId", "ToppingId"); - - b.HasIndex("ToppingId"); - - b.ToTable("OrderToppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Price") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.ToTable("Pizzas"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => - { - b.Property("id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("id")); - - b.Property("cost") - .HasColumnType("integer"); - - b.Property("name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("id"); - - b.ToTable("Toppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.HasOne("exercise.pizzashopapi.Models.Customer", "Customer") - .WithMany("Orders") - .HasForeignKey("customerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("exercise.pizzashopapi.Models.Pizza", "Pizza") - .WithMany() - .HasForeignKey("pizzaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Customer"); - - b.Navigation("Pizza"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => - { - b.HasOne("exercise.pizzashopapi.Models.Order", "Order") - .WithMany("toppings") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("exercise.pizzashopapi.Models.Toppings", "Topping") - .WithMany("OrderToppings") - .HasForeignKey("ToppingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Order"); - - b.Navigation("Topping"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.Navigation("toppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => - { - b.Navigation("OrderToppings"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/exercise.pizzashopapi/Migrations/20250127122917_first.cs b/exercise.pizzashopapi/Migrations/20250127122917_first.cs deleted file mode 100644 index 65c4494..0000000 --- a/exercise.pizzashopapi/Migrations/20250127122917_first.cs +++ /dev/null @@ -1,140 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace exercise.pizzashopapi.Migrations -{ - /// - public partial class first : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Customers", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "text", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Customers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Pizzas", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(type: "text", nullable: false), - Price = table.Column(type: "numeric", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Pizzas", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Toppings", - columns: table => new - { - id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - name = table.Column(type: "text", nullable: false), - cost = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Toppings", x => x.id); - }); - - migrationBuilder.CreateTable( - name: "Orders", - columns: table => new - { - orderId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - customerId = table.Column(type: "integer", nullable: false), - pizzaId = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Orders", x => x.orderId); - table.ForeignKey( - name: "FK_Orders_Customers_customerId", - column: x => x.customerId, - principalTable: "Customers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Orders_Pizzas_pizzaId", - column: x => x.pizzaId, - principalTable: "Pizzas", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "OrderToppings", - columns: table => new - { - OrderId = table.Column(type: "integer", nullable: false), - ToppingId = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_OrderToppings", x => new { x.OrderId, x.ToppingId }); - table.ForeignKey( - name: "FK_OrderToppings_Orders_OrderId", - column: x => x.OrderId, - principalTable: "Orders", - principalColumn: "orderId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_OrderToppings_Toppings_ToppingId", - column: x => x.ToppingId, - principalTable: "Toppings", - principalColumn: "id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_Orders_customerId", - table: "Orders", - column: "customerId"); - - migrationBuilder.CreateIndex( - name: "IX_Orders_pizzaId", - table: "Orders", - column: "pizzaId"); - - migrationBuilder.CreateIndex( - name: "IX_OrderToppings_ToppingId", - table: "OrderToppings", - column: "ToppingId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "OrderToppings"); - - migrationBuilder.DropTable( - name: "Orders"); - - migrationBuilder.DropTable( - name: "Toppings"); - - migrationBuilder.DropTable( - name: "Customers"); - - migrationBuilder.DropTable( - name: "Pizzas"); - } - } -} diff --git a/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs deleted file mode 100644 index 1c44544..0000000 --- a/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs +++ /dev/null @@ -1,174 +0,0 @@ -// -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; -using exercise.pizzashopapi.Data; - -#nullable disable - -namespace exercise.pizzashopapi.Migrations -{ - [DbContext(typeof(DataContext))] - partial class DataContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "7.0.11") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Customers"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.Property("orderId") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("orderId")); - - b.Property("customerId") - .HasColumnType("integer"); - - b.Property("pizzaId") - .HasColumnType("integer"); - - b.HasKey("orderId"); - - b.HasIndex("customerId"); - - b.HasIndex("pizzaId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => - { - b.Property("OrderId") - .HasColumnType("integer"); - - b.Property("ToppingId") - .HasColumnType("integer"); - - b.HasKey("OrderId", "ToppingId"); - - b.HasIndex("ToppingId"); - - b.ToTable("OrderToppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Name") - .IsRequired() - .HasColumnType("text"); - - b.Property("Price") - .HasColumnType("numeric"); - - b.HasKey("Id"); - - b.ToTable("Pizzas"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => - { - b.Property("id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("id")); - - b.Property("cost") - .HasColumnType("integer"); - - b.Property("name") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("id"); - - b.ToTable("Toppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.HasOne("exercise.pizzashopapi.Models.Customer", "Customer") - .WithMany("Orders") - .HasForeignKey("customerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("exercise.pizzashopapi.Models.Pizza", "Pizza") - .WithMany() - .HasForeignKey("pizzaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Customer"); - - b.Navigation("Pizza"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.OrderToppings", b => - { - b.HasOne("exercise.pizzashopapi.Models.Order", "Order") - .WithMany("toppings") - .HasForeignKey("OrderId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("exercise.pizzashopapi.Models.Toppings", "Topping") - .WithMany("OrderToppings") - .HasForeignKey("ToppingId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Order"); - - b.Navigation("Topping"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => - { - b.Navigation("Orders"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => - { - b.Navigation("toppings"); - }); - - modelBuilder.Entity("exercise.pizzashopapi.Models.Toppings", b => - { - b.Navigation("OrderToppings"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/exercise.pizzashopapi/Models/Order.cs b/exercise.pizzashopapi/Models/Order.cs index a4812b8..36f6fe8 100644 --- a/exercise.pizzashopapi/Models/Order.cs +++ b/exercise.pizzashopapi/Models/Order.cs @@ -6,13 +6,13 @@ public class Order { public int orderId { get; set; } public int customerId { get; set; } - public int pizzaId { get; set; } + public int productId { get; set; } public List toppings { get; set; } public Customer Customer { get; set; } - public Pizza Pizza { get; set; } + public Product Product { get; set; } } } diff --git a/exercise.pizzashopapi/Models/Pizza.cs b/exercise.pizzashopapi/Models/Product.cs similarity index 78% rename from exercise.pizzashopapi/Models/Pizza.cs rename to exercise.pizzashopapi/Models/Product.cs index 649b610..134a2c7 100644 --- a/exercise.pizzashopapi/Models/Pizza.cs +++ b/exercise.pizzashopapi/Models/Product.cs @@ -3,9 +3,10 @@ namespace exercise.pizzashopapi.Models { - public class Pizza + public class Product { public int Id { get; set; } + public string Type { get; set; } public string Name { get; set; } public decimal Price { get; set; } diff --git a/exercise.pizzashopapi/Program.cs b/exercise.pizzashopapi/Program.cs index c04a440..32107be 100644 --- a/exercise.pizzashopapi/Program.cs +++ b/exercise.pizzashopapi/Program.cs @@ -28,8 +28,8 @@ app.MapControllers(); -app.ConfigurePizzaShopApi(); +app.ConfigureProductShopApi(); -app.SeedPizzaShopApi(); +app.SeedProductShopApi(); app.Run(); diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index 8427ede..79dd344 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -5,11 +5,11 @@ namespace exercise.pizzashopapi.Repository public interface IRepository { Task> GetOrdersByCustomer(int id); - Task> GetPizzas(); + Task> GetProducts(); Task> GetCustomers(); Task> GetOrders(); TaskGetOrderById(int id); - Task GetPizzaById(int id); + Task GetProductById(int id); Task GetToppingsById(int id); } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index 827c88c..c77a973 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -19,9 +19,9 @@ public async Task> GetOrdersByCustomer(int id) return orders; } - public async Task> GetPizzas() + public async Task> GetProducts() { - return await _db.Pizzas.ToListAsync(); + return await _db.Products.ToListAsync(); } public async Task> GetCustomers() @@ -58,9 +58,9 @@ public async TaskAddToppingToOrder(Toppings topping, OrderTopping return top; } - public async Task GetPizzaById(int id) + public async Task GetProductById(int id) { - return _db.Pizzas.Where(x => x.Id == id).FirstOrDefault()!; + return _db.Products.Where(x => x.Id == id).FirstOrDefault()!; } public async Task GetToppingsById(int id)