From d0a90eb4a93295dd2b28b8716c7ef43a88b6449a Mon Sep 17 00:00:00 2001 From: abdi Date: Tue, 28 Jan 2025 12:36:29 +0100 Subject: [PATCH] core --- exercise.pizzashopapi/DTO/CustomerDTO.cs | 11 + exercise.pizzashopapi/DTO/OrderDTO.cs | 8 + exercise.pizzashopapi/DTO/PizzaDTO.cs | 11 + exercise.pizzashopapi/Data/DataContext.cs | 34 +- exercise.pizzashopapi/Data/Seeder.cs | 94 ++++- .../EndPoints/PizzaShopApi.cs | 118 +++++- ...0250128091222_InitialMigration.Designer.cs | 380 ++++++++++++++++++ .../20250128091222_InitialMigration.cs | 156 +++++++ .../Migrations/DataContextModelSnapshot.cs | 377 +++++++++++++++++ exercise.pizzashopapi/Models/Customer.cs | 4 + exercise.pizzashopapi/Models/Order.cs | 8 + exercise.pizzashopapi/Models/Pizza.cs | 10 +- exercise.pizzashopapi/Program.cs | 50 ++- .../Repository/IRepository.cs | 27 +- .../Repository/Repository.cs | 42 +- .../exercise.pizzashopapi.csproj | 2 +- 16 files changed, 1284 insertions(+), 48 deletions(-) create mode 100644 exercise.pizzashopapi/DTO/CustomerDTO.cs create mode 100644 exercise.pizzashopapi/DTO/OrderDTO.cs create mode 100644 exercise.pizzashopapi/DTO/PizzaDTO.cs create mode 100644 exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.Designer.cs create mode 100644 exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.cs create mode 100644 exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs diff --git a/exercise.pizzashopapi/DTO/CustomerDTO.cs b/exercise.pizzashopapi/DTO/CustomerDTO.cs new file mode 100644 index 0000000..03d2876 --- /dev/null +++ b/exercise.pizzashopapi/DTO/CustomerDTO.cs @@ -0,0 +1,11 @@ +namespace exercise.pizzashopapi.DTO +{ + public class CustomerDTO + { + public int Id { get; set; } + public string Name { get; set; } + + public List Orders { get; set; } + + } +} diff --git a/exercise.pizzashopapi/DTO/OrderDTO.cs b/exercise.pizzashopapi/DTO/OrderDTO.cs new file mode 100644 index 0000000..bf88999 --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderDTO.cs @@ -0,0 +1,8 @@ +namespace exercise.pizzashopapi.DTO +{ + public class OrderDTO + { + public string PizzaName { get; set; } + public string CustomerName { get; set; } + } +} diff --git a/exercise.pizzashopapi/DTO/PizzaDTO.cs b/exercise.pizzashopapi/DTO/PizzaDTO.cs new file mode 100644 index 0000000..ec1c2ff --- /dev/null +++ b/exercise.pizzashopapi/DTO/PizzaDTO.cs @@ -0,0 +1,11 @@ +namespace exercise.pizzashopapi.DTO +{ + public class PizzaDTO + { + public int Id { get; set; } + + public string Name { get; set; } + + public decimal Price { get; set; } + } +} diff --git a/exercise.pizzashopapi/Data/DataContext.cs b/exercise.pizzashopapi/Data/DataContext.cs index 129199e..29ce78c 100644 --- a/exercise.pizzashopapi/Data/DataContext.cs +++ b/exercise.pizzashopapi/Data/DataContext.cs @@ -5,22 +5,38 @@ namespace exercise.pizzashopapi.Data { public class DataContext : DbContext { - private string connectionString; - public DataContext() + public DataContext(DbContextOptions options) : base(options) { } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); - connectionString = configuration.GetValue("ConnectionStrings:DefaultConnectionString"); + if (!optionsBuilder.IsConfigured) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) + .AddJsonFile("appsettings.json") + .Build(); + var connectionString = configuration.GetConnectionString("DefaultConnectionString"); + optionsBuilder.UseNpgsql(connectionString); + } + base.OnConfiguring(optionsBuilder); } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseNpgsql(connectionString); - //set primary of order? + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + Seeder seeder = new Seeder(); - //seed data? + // Generate data + var pizzas = seeder.GetPizzas(); + var customers = seeder.GetCustomers(); + var orders = seeder.GetOrders(pizzas, customers); + // Seed data + modelBuilder.Entity().HasData(pizzas); + modelBuilder.Entity().HasData(customers); + modelBuilder.Entity().HasData(orders); } + public DbSet Pizzas { get; set; } public DbSet Customers { get; set; } public DbSet Orders { get; set; } diff --git a/exercise.pizzashopapi/Data/Seeder.cs b/exercise.pizzashopapi/Data/Seeder.cs index f87fbef..73996c4 100644 --- a/exercise.pizzashopapi/Data/Seeder.cs +++ b/exercise.pizzashopapi/Data/Seeder.cs @@ -2,33 +2,91 @@ namespace exercise.pizzashopapi.Data { - public static class Seeder + public class Seeder { - public async static void SeedPizzaShopApi(this WebApplication app) + private List _pizzaNames = new List { - using(var db = new DataContext()) + "Cheese & Pineapple", + "Vegan Cheese Tastic", + "Pepperoni Feast", + "BBQ Chicken Delight", + "Margarita Supreme", + "Four Seasons", + "Meat Lover's Special", + "Spicy Veggie", + "Garlic Mushroom", + "Buffalo Ranch" + }; + + private List _customerNames = new List + { + "Nigel", + "Dave", + "Alice", + "Bob", + "Charlie", + "Diana", + "Edward", + "Fiona", + "George", + "Hannah" + }; + + public List GetPizzas() + { + Random random = new Random(); + var pizzas = new List(); + + for (int i = 1; i <= _pizzaNames.Count; i++) { - if(!db.Customers.Any()) - { - db.Add(new Customer() { Name="Nigel" }); - db.Add(new Customer() { Name = "Dave" }); - await db.SaveChangesAsync(); - } - if(!db.Pizzas.Any()) + pizzas.Add(new Pizza { - db.Add(new Pizza() { Name = "Cheese & Pineapple" }); - db.Add(new Pizza() { Name = "Vegan Cheese Tastic" }); - await db.SaveChangesAsync(); + Id = i, + Name = _pizzaNames[i - 1], + Price = random.Next(100, 500) // Random price between 100 and 500 + }); + } + return pizzas; + } - } + public List GetCustomers() + { + var customers = new List(); - //order data - if(1==1) + for (int i = 1; i <= _customerNames.Count; i++) + { + customers.Add(new Customer { + Id = i, + Name = _customerNames[i - 1] + }); + } + return customers; + } + + public List GetOrders(List pizzas, List customers) + { + var orders = new List(); + Random random = new Random(); + int orderId = 1; + + for (int i = 1; i <= 20; i++) // Create 20 random orders + { + var randomPizza = pizzas[random.Next(pizzas.Count)]; + var randomCustomer = customers[random.Next(customers.Count)]; - await db.SaveChangesAsync(); - } + orders.Add(new Order + { + Id = orderId++, + PizzaId = randomPizza.Id, + CustomerId = randomCustomer.Id + }); } + + return orders; } } } + + + diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs index f8be2b0..d5f4479 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,119 @@ public static class PizzaShopApi { public static void ConfigurePizzaShopApi(this WebApplication app) { - + var shopGroup = app.MapGroup("PizzaShop"); + + shopGroup.MapGet("/Customers", GetCustomers); + shopGroup.MapGet("/Customer", GetCustomer); + + shopGroup.MapGet("/Pizzas", GetPizzas); + shopGroup.MapGet("/Pizza", GetPizza); + + shopGroup.MapGet("/Orders", GetOrders); + shopGroup.MapGet("/OrderbyPizza", GetOrderByPizza); + shopGroup.MapGet("/OrderbyCustomer", GetOrderByCustomer); + + } + + private static async Task GetOrderByCustomer(IRepository repository, int id) + { + var customerorders = await repository.GetOrdersByCustomer(id); + var customerordersDtos = customerorders.Select(o => new OrderDTO + { + + PizzaName = o.Pizza.Name, + CustomerName = o.Customer.Name + }).ToList(); + + return TypedResults.Ok(customerordersDtos); + } + + private static async Task GetOrderByPizza(IRepository repository, int id ) + { + var pizzaorders = await repository.GetOrdersByPizza(id); + var pizzaordersDtos = pizzaorders.Select(o => new OrderDTO + { + + PizzaName = o.Pizza.Name, + CustomerName = o.Customer.Name + }).ToList(); + + return TypedResults.Ok(pizzaordersDtos); + + } + + private static async Task GetPizza(IRepository repository, int id) + { + var pizza = await repository.GetPizzaById(id); + + PizzaDTO dto = new PizzaDTO(); + dto.Id = id; + dto.Name = pizza.Name; + + + + return TypedResults.Ok(dto); + } + + private static async Task GetCustomer(IRepository repository, int id) + { + var customer = await repository.GetCustomerById(id); + + CustomerDTO dto = new CustomerDTO(); + dto.Id = id; + dto.Name = customer.Name; + + + + return TypedResults.Ok(dto); + } + + private static async Task GetOrders(IRepository repository) + { + var orders = await repository.GetOrders(); + + var orderDtos = orders.Select(o => new OrderDTO + { + + CustomerName = o.Customer.Name, + PizzaName = o.Pizza.Name + }).ToList(); + + return TypedResults.Ok(orderDtos); + + + + } + + private static async Task GetPizzas(IRepository repository) + { + var pizzas = await repository.GetPizzas(); + + var pizzasDtos = pizzas.Select(p => new PizzaDTO + { + Id = p.Id, + Name = p.Name, + Price = p.Price + }).ToList(); + + return TypedResults.Ok(pizzasDtos); + + + } - + private static async Task GetCustomers(IRepository repository) + { + var customers = await repository.GetCustomers(); + + var customerDtos = customers.Select(c => new CustomerDTO + { + Id = c.Id, + Name = c.Name, + }).ToList(); + + + return TypedResults.Ok(customerDtos); + } } } diff --git a/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.Designer.cs b/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.Designer.cs new file mode 100644 index 0000000..934be97 --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.Designer.cs @@ -0,0 +1,380 @@ +// +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("20250128091222_InitialMigration")] + partial class InitialMigration + { + /// + 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.Property("OrderId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Customers"); + + b.HasData( + new + { + Id = 1, + Name = "Nigel", + OrderId = 0 + }, + new + { + Id = 2, + Name = "Dave", + OrderId = 0 + }, + new + { + Id = 3, + Name = "Alice", + OrderId = 0 + }, + new + { + Id = 4, + Name = "Bob", + OrderId = 0 + }, + new + { + Id = 5, + Name = "Charlie", + OrderId = 0 + }, + new + { + Id = 6, + Name = "Diana", + OrderId = 0 + }, + new + { + Id = 7, + Name = "Edward", + OrderId = 0 + }, + new + { + Id = 8, + Name = "Fiona", + OrderId = 0 + }, + new + { + Id = 9, + Name = "George", + OrderId = 0 + }, + new + { + Id = 10, + Name = "Hannah", + OrderId = 0 + }); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CustomerId") + .HasColumnType("integer"); + + b.Property("PizzaId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.HasIndex("PizzaId"); + + b.ToTable("Orders"); + + b.HasData( + new + { + Id = 1, + CustomerId = 7, + PizzaId = 6 + }, + new + { + Id = 2, + CustomerId = 3, + PizzaId = 8 + }, + new + { + Id = 3, + CustomerId = 2, + PizzaId = 8 + }, + new + { + Id = 4, + CustomerId = 1, + PizzaId = 2 + }, + new + { + Id = 5, + CustomerId = 3, + PizzaId = 8 + }, + new + { + Id = 6, + CustomerId = 8, + PizzaId = 3 + }, + new + { + Id = 7, + CustomerId = 2, + PizzaId = 6 + }, + new + { + Id = 8, + CustomerId = 5, + PizzaId = 4 + }, + new + { + Id = 9, + CustomerId = 2, + PizzaId = 2 + }, + new + { + Id = 10, + CustomerId = 5, + PizzaId = 1 + }, + new + { + Id = 11, + CustomerId = 4, + PizzaId = 3 + }, + new + { + Id = 12, + CustomerId = 10, + PizzaId = 6 + }, + new + { + Id = 13, + CustomerId = 6, + PizzaId = 4 + }, + new + { + Id = 14, + CustomerId = 7, + PizzaId = 9 + }, + new + { + Id = 15, + CustomerId = 6, + PizzaId = 9 + }, + new + { + Id = 16, + CustomerId = 3, + PizzaId = 4 + }, + new + { + Id = 17, + CustomerId = 10, + PizzaId = 2 + }, + new + { + Id = 18, + CustomerId = 2, + PizzaId = 9 + }, + new + { + Id = 19, + CustomerId = 3, + PizzaId = 5 + }, + new + { + Id = 20, + CustomerId = 5, + PizzaId = 8 + }); + }); + + 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("OrderId") + .HasColumnType("integer"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.ToTable("Pizzas"); + + b.HasData( + new + { + Id = 1, + Name = "Cheese & Pineapple", + OrderId = 0, + Price = 393m + }, + new + { + Id = 2, + Name = "Vegan Cheese Tastic", + OrderId = 0, + Price = 498m + }, + new + { + Id = 3, + Name = "Pepperoni Feast", + OrderId = 0, + Price = 227m + }, + new + { + Id = 4, + Name = "BBQ Chicken Delight", + OrderId = 0, + Price = 398m + }, + new + { + Id = 5, + Name = "Margarita Supreme", + OrderId = 0, + Price = 272m + }, + new + { + Id = 6, + Name = "Four Seasons", + OrderId = 0, + Price = 376m + }, + new + { + Id = 7, + Name = "Meat Lover's Special", + OrderId = 0, + Price = 378m + }, + new + { + Id = 8, + Name = "Spicy Veggie", + OrderId = 0, + Price = 196m + }, + new + { + Id = 9, + Name = "Garlic Mushroom", + OrderId = 0, + Price = 156m + }, + new + { + Id = 10, + Name = "Buffalo Ranch", + OrderId = 0, + Price = 140m + }); + }); + + 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("Orders") + .HasForeignKey("PizzaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Pizza"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.cs b/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.cs new file mode 100644 index 0000000..8c59211 --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250128091222_InitialMigration.cs @@ -0,0 +1,156 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace exercise.pizzashopapi.Migrations +{ + /// + public partial class InitialMigration : 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), + OrderId = table.Column(type: "integer", 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), + OrderId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Pizzas", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PizzaId = table.Column(type: "integer", nullable: false), + CustomerId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + 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.InsertData( + table: "Customers", + columns: new[] { "Id", "Name", "OrderId" }, + values: new object[,] + { + { 1, "Nigel", 0 }, + { 2, "Dave", 0 }, + { 3, "Alice", 0 }, + { 4, "Bob", 0 }, + { 5, "Charlie", 0 }, + { 6, "Diana", 0 }, + { 7, "Edward", 0 }, + { 8, "Fiona", 0 }, + { 9, "George", 0 }, + { 10, "Hannah", 0 } + }); + + migrationBuilder.InsertData( + table: "Pizzas", + columns: new[] { "Id", "Name", "OrderId", "Price" }, + values: new object[,] + { + { 1, "Cheese & Pineapple", 0, 393m }, + { 2, "Vegan Cheese Tastic", 0, 498m }, + { 3, "Pepperoni Feast", 0, 227m }, + { 4, "BBQ Chicken Delight", 0, 398m }, + { 5, "Margarita Supreme", 0, 272m }, + { 6, "Four Seasons", 0, 376m }, + { 7, "Meat Lover's Special", 0, 378m }, + { 8, "Spicy Veggie", 0, 196m }, + { 9, "Garlic Mushroom", 0, 156m }, + { 10, "Buffalo Ranch", 0, 140m } + }); + + migrationBuilder.InsertData( + table: "Orders", + columns: new[] { "Id", "CustomerId", "PizzaId" }, + values: new object[,] + { + { 1, 7, 6 }, + { 2, 3, 8 }, + { 3, 2, 8 }, + { 4, 1, 2 }, + { 5, 3, 8 }, + { 6, 8, 3 }, + { 7, 2, 6 }, + { 8, 5, 4 }, + { 9, 2, 2 }, + { 10, 5, 1 }, + { 11, 4, 3 }, + { 12, 10, 6 }, + { 13, 6, 4 }, + { 14, 7, 9 }, + { 15, 6, 9 }, + { 16, 3, 4 }, + { 17, 10, 2 }, + { 18, 2, 9 }, + { 19, 3, 5 }, + { 20, 5, 8 } + }); + + migrationBuilder.CreateIndex( + name: "IX_Orders_CustomerId", + table: "Orders", + column: "CustomerId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_PizzaId", + table: "Orders", + column: "PizzaId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Orders"); + + 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..fe3e36b --- /dev/null +++ b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs @@ -0,0 +1,377 @@ +// +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.Property("OrderId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("Customers"); + + b.HasData( + new + { + Id = 1, + Name = "Nigel", + OrderId = 0 + }, + new + { + Id = 2, + Name = "Dave", + OrderId = 0 + }, + new + { + Id = 3, + Name = "Alice", + OrderId = 0 + }, + new + { + Id = 4, + Name = "Bob", + OrderId = 0 + }, + new + { + Id = 5, + Name = "Charlie", + OrderId = 0 + }, + new + { + Id = 6, + Name = "Diana", + OrderId = 0 + }, + new + { + Id = 7, + Name = "Edward", + OrderId = 0 + }, + new + { + Id = 8, + Name = "Fiona", + OrderId = 0 + }, + new + { + Id = 9, + Name = "George", + OrderId = 0 + }, + new + { + Id = 10, + Name = "Hannah", + OrderId = 0 + }); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CustomerId") + .HasColumnType("integer"); + + b.Property("PizzaId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CustomerId"); + + b.HasIndex("PizzaId"); + + b.ToTable("Orders"); + + b.HasData( + new + { + Id = 1, + CustomerId = 7, + PizzaId = 6 + }, + new + { + Id = 2, + CustomerId = 3, + PizzaId = 8 + }, + new + { + Id = 3, + CustomerId = 2, + PizzaId = 8 + }, + new + { + Id = 4, + CustomerId = 1, + PizzaId = 2 + }, + new + { + Id = 5, + CustomerId = 3, + PizzaId = 8 + }, + new + { + Id = 6, + CustomerId = 8, + PizzaId = 3 + }, + new + { + Id = 7, + CustomerId = 2, + PizzaId = 6 + }, + new + { + Id = 8, + CustomerId = 5, + PizzaId = 4 + }, + new + { + Id = 9, + CustomerId = 2, + PizzaId = 2 + }, + new + { + Id = 10, + CustomerId = 5, + PizzaId = 1 + }, + new + { + Id = 11, + CustomerId = 4, + PizzaId = 3 + }, + new + { + Id = 12, + CustomerId = 10, + PizzaId = 6 + }, + new + { + Id = 13, + CustomerId = 6, + PizzaId = 4 + }, + new + { + Id = 14, + CustomerId = 7, + PizzaId = 9 + }, + new + { + Id = 15, + CustomerId = 6, + PizzaId = 9 + }, + new + { + Id = 16, + CustomerId = 3, + PizzaId = 4 + }, + new + { + Id = 17, + CustomerId = 10, + PizzaId = 2 + }, + new + { + Id = 18, + CustomerId = 2, + PizzaId = 9 + }, + new + { + Id = 19, + CustomerId = 3, + PizzaId = 5 + }, + new + { + Id = 20, + CustomerId = 5, + PizzaId = 8 + }); + }); + + 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("OrderId") + .HasColumnType("integer"); + + b.Property("Price") + .HasColumnType("numeric"); + + b.HasKey("Id"); + + b.ToTable("Pizzas"); + + b.HasData( + new + { + Id = 1, + Name = "Cheese & Pineapple", + OrderId = 0, + Price = 393m + }, + new + { + Id = 2, + Name = "Vegan Cheese Tastic", + OrderId = 0, + Price = 498m + }, + new + { + Id = 3, + Name = "Pepperoni Feast", + OrderId = 0, + Price = 227m + }, + new + { + Id = 4, + Name = "BBQ Chicken Delight", + OrderId = 0, + Price = 398m + }, + new + { + Id = 5, + Name = "Margarita Supreme", + OrderId = 0, + Price = 272m + }, + new + { + Id = 6, + Name = "Four Seasons", + OrderId = 0, + Price = 376m + }, + new + { + Id = 7, + Name = "Meat Lover's Special", + OrderId = 0, + Price = 378m + }, + new + { + Id = 8, + Name = "Spicy Veggie", + OrderId = 0, + Price = 196m + }, + new + { + Id = 9, + Name = "Garlic Mushroom", + OrderId = 0, + Price = 156m + }, + new + { + Id = 10, + Name = "Buffalo Ranch", + OrderId = 0, + Price = 140m + }); + }); + + 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("Orders") + .HasForeignKey("PizzaId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Customer"); + + b.Navigation("Pizza"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Customer", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Navigation("Orders"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/exercise.pizzashopapi/Models/Customer.cs b/exercise.pizzashopapi/Models/Customer.cs index 2ca83bd..9dc33c9 100644 --- a/exercise.pizzashopapi/Models/Customer.cs +++ b/exercise.pizzashopapi/Models/Customer.cs @@ -6,5 +6,9 @@ public class Customer { public int Id { get; set; } public string Name { get; set; } + + public int OrderId { get; set; } + + public List Orders { get; set; } } } diff --git a/exercise.pizzashopapi/Models/Order.cs b/exercise.pizzashopapi/Models/Order.cs index fbe6113..07c434a 100644 --- a/exercise.pizzashopapi/Models/Order.cs +++ b/exercise.pizzashopapi/Models/Order.cs @@ -4,6 +4,14 @@ namespace exercise.pizzashopapi.Models { public class Order { + public int Id { get; set; } + public int PizzaId { get; set; } + + public int CustomerId { get; set; } + + public Pizza Pizza { get; set; } + + public Customer Customer { get; set; } } diff --git a/exercise.pizzashopapi/Models/Pizza.cs b/exercise.pizzashopapi/Models/Pizza.cs index 5c085ec..27b9866 100644 --- a/exercise.pizzashopapi/Models/Pizza.cs +++ b/exercise.pizzashopapi/Models/Pizza.cs @@ -2,11 +2,17 @@ namespace exercise.pizzashopapi.Models { - + public class Pizza - { + { + public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } + + public int OrderId { get; set; } + public List Orders { get; set; } + + } } \ No newline at end of file diff --git a/exercise.pizzashopapi/Program.cs b/exercise.pizzashopapi/Program.cs index c04a440..cdeaf42 100644 --- a/exercise.pizzashopapi/Program.cs +++ b/exercise.pizzashopapi/Program.cs @@ -1,21 +1,50 @@ using exercise.pizzashopapi.Data; using exercise.pizzashopapi.EndPoints; using exercise.pizzashopapi.Repository; +using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); -// Add services to the container. +// Legg til tjenester i DI-containeren +builder.Services.AddControllers(); // Legger til støtte for kontroller +builder.Services.AddScoped(); // Registrer repository +builder.Services.AddDbContext(options => +{ + var connectionString = builder.Configuration.GetConnectionString("DefaultConnectionString"); + options.UseNpgsql(connectionString); +}); -builder.Services.AddControllers(); -builder.Services.AddScoped(); -builder.Services.AddDbContext(); -// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +// Legg til Swagger for API-dokumentasjon builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); -// Configure the HTTP request pipeline. +// Utfør migrasjoner og seeding ved oppstart +using (var scope = app.Services.CreateScope()) +{ + var dbContext = scope.ServiceProvider.GetRequiredService(); + + // Kjør migrasjoner for å sikre at databasen er oppdatert + dbContext.Database.Migrate(); + + // Seed data hvis databasen er tom + var seeder = new Seeder(); + if (!dbContext.Pizzas.Any() && !dbContext.Customers.Any() && !dbContext.Orders.Any()) + { + var pizzas = seeder.GetPizzas(); + var customers = seeder.GetCustomers(); + var orders = seeder.GetOrders(pizzas, customers); + + dbContext.Pizzas.AddRange(pizzas); + dbContext.Customers.AddRange(customers); + dbContext.Orders.AddRange(orders); + + await dbContext.SaveChangesAsync(); + } +} + +// Konfigurer middleware og HTTP-pipeline if (app.Environment.IsDevelopment()) { app.UseSwagger(); @@ -23,13 +52,10 @@ } app.UseHttpsRedirection(); - app.UseAuthorization(); -app.MapControllers(); - -app.ConfigurePizzaShopApi(); - -app.SeedPizzaShopApi(); +app.MapControllers(); // Mapper kontrollerne som API-endepunkter +PizzaShopApi.ConfigurePizzaShopApi(app); +// Kjør applikasjonen app.Run(); diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index b114ea8..24f56e5 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -5,7 +5,32 @@ namespace exercise.pizzashopapi.Repository public interface IRepository { Task> GetOrdersByCustomer(int id); - + + Task> GetOrdersByPizza(int id); + + + Task> GetOrders(); + + + Task> GetCustomers(); + + Task> GetPizzas(); + + + Task GetCustomerById(int id); + + Task GetPizzaById(int id); + + + + + + + + + + + } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index e109fce..8dcc4ff 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -1,14 +1,52 @@ 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 GetCustomerById(int id) + { + return await _db.Customers.Include(c => c.Orders).FirstOrDefaultAsync(c => c.Id == id); + } + + public async Task> GetCustomers() + { + return await _db.Customers.Include(c => c.Orders).ToListAsync(); + } + + public async Task> GetOrders() + { + return await _db.Orders.Include(o=>o.Customer).Include(o=>o.Pizza).ToListAsync(); + + } + + public async Task> GetOrdersByCustomer(int id) + { + return await _db.Orders.Include(o => o.Pizza).Include(o => o.Customer).Where(o => o.CustomerId == id).ToListAsync(); + } + + public async Task> GetOrdersByPizza(int id) + { + return await _db.Orders.Include(o => o.Pizza).Include(o => o.Customer).Where(o => o.PizzaId == id).ToListAsync(); + } + + public async Task GetPizzaById(int id) + { + return await _db.Pizzas.Include(p => p.Orders).FirstOrDefaultAsync(p => p.Id == id); + } + + public async Task> GetPizzas() { - throw new NotImplementedException(); + return await _db.Pizzas.Include(p=>p.Orders).ToListAsync() ; } } } diff --git a/exercise.pizzashopapi/exercise.pizzashopapi.csproj b/exercise.pizzashopapi/exercise.pizzashopapi.csproj index 624203b..abb3483 100644 --- a/exercise.pizzashopapi/exercise.pizzashopapi.csproj +++ b/exercise.pizzashopapi/exercise.pizzashopapi.csproj @@ -1,4 +1,4 @@ - + net9.0