diff --git a/exercise.pizzashopapi/DTO/CustomerDTO.cs b/exercise.pizzashopapi/DTO/CustomerDTO.cs new file mode 100644 index 0000000..6104543 --- /dev/null +++ b/exercise.pizzashopapi/DTO/CustomerDTO.cs @@ -0,0 +1,19 @@ +using exercise.pizzashopapi.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace exercise.pizzashopapi.DTO +{ + public class CustomerDTO + { + public int Id { get; set; } + public string Name { get; set; } + public List Orders { get; set; } = new List(); + + public CustomerDTO(Customer customer) + { + Id = customer.customerId; + Name = customer.Name; + customer.Orders.ForEach(x => Orders.Add($"{x.pizza.Name}")); + } + } +} diff --git a/exercise.pizzashopapi/DTO/OrderDTO.cs b/exercise.pizzashopapi/DTO/OrderDTO.cs new file mode 100644 index 0000000..4d4a090 --- /dev/null +++ b/exercise.pizzashopapi/DTO/OrderDTO.cs @@ -0,0 +1,24 @@ +using exercise.pizzashopapi.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace exercise.pizzashopapi.DTO +{ + public class OrderDTO + { + + public int Id { get; set; } + public string customer { get; set; } + public string pizza { get; set; } = ""; + public List toppings { get; set; } = new List(); + public string status { get; set; } + + public OrderDTO(Order order) + { + Id = order.orderId; + customer= order.customer.Name; + pizza=$"{order.pizza.Name} {order.pizza.Price}"; + order.OrderToppings.ForEach(x => toppings.Add(x.topping.topping)); + status = order.status; + } + } +} diff --git a/exercise.pizzashopapi/DTO/PizzaDTO.cs b/exercise.pizzashopapi/DTO/PizzaDTO.cs new file mode 100644 index 0000000..e82f0b5 --- /dev/null +++ b/exercise.pizzashopapi/DTO/PizzaDTO.cs @@ -0,0 +1,21 @@ +using exercise.pizzashopapi.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace exercise.pizzashopapi.DTO +{ + public class PizzaDTO + { + public int Id { get; set; } + public string Name { get; set; } + public decimal Price { get; set; } + public List Orders { get; set; } = new List(); + public PizzaDTO(Pizza pizza) + { + Id = pizza.pizzaId; + Name = pizza.Name; + Price = pizza.Price; + pizza.Orders.ForEach(x => Orders.Add($"{x.pizza} {x.customer}")); + + } + } +} diff --git a/exercise.pizzashopapi/Data/DataContext.cs b/exercise.pizzashopapi/Data/DataContext.cs index 129199e..d63b143 100644 --- a/exercise.pizzashopapi/Data/DataContext.cs +++ b/exercise.pizzashopapi/Data/DataContext.cs @@ -1,4 +1,5 @@ -using exercise.pizzashopapi.Models; +using api_cinema_challenge.Models; +using exercise.pizzashopapi.Models; using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Data @@ -6,23 +7,90 @@ namespace exercise.pizzashopapi.Data public class DataContext : DbContext { private string connectionString; - public DataContext() +public DataContext() { var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build(); - connectionString = configuration.GetValue("ConnectionStrings:DefaultConnectionString"); - + connectionString = configuration.GetValue("ConnectionStrings:DefaultConnectionString")!; + this.Database.SetConnectionString(connectionString); + this.Database.EnsureCreated(); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { + { optionsBuilder.UseNpgsql(connectionString); + optionsBuilder.UseLazyLoadingProxies(); //set primary of order? //seed data? } + protected override async void OnModelCreating(ModelBuilder modelBuilder) + { + //defining primary keys + modelBuilder.Entity() + .HasKey(a => a.customerId); + modelBuilder.Entity() + .HasKey(a => a.pizzaId); + modelBuilder.Entity() + .HasKey(a => a.orderId); + modelBuilder.Entity() + .HasKey(a => a.toppingId); + modelBuilder.Entity() + .HasKey(a => a.orderToppingId); + + + //defining relations + modelBuilder.Entity() + .HasMany(a => a.Orders) + .WithOne(a => a.customer) + .HasForeignKey(a => a.customerId); + + modelBuilder.Entity() + .HasMany(a => a.Orders) + .WithOne(a => a.pizza); + + + modelBuilder.Entity() + .HasOne(a => a.pizza) + .WithMany(a => a.Orders) + .HasForeignKey(a => a.pizzaId); + + + modelBuilder.Entity() + .HasOne(a => a.customer) + .WithMany(a => a.Orders) + .HasForeignKey(a => a.customerId); + + modelBuilder.Entity() + .HasMany(a => a.OrderToppings) + .WithOne(a => a.order); + + + modelBuilder.Entity() + .HasOne(a => a.order) + .WithMany(a => a.OrderToppings) + .HasForeignKey(a => a.orderId); + + modelBuilder.Entity() + .HasOne(a => a.topping) + .WithMany(a => a.orderToppings) + .HasForeignKey(a => a.toppingId); + + modelBuilder.Entity() + .HasMany(a => a.orderToppings) + .WithOne(a => a.topping); + + //seeding + + + } + + public DbSet Pizzas { get; set; } public DbSet Customers { get; set; } public DbSet Orders { get; set; } + public DbSet OrderToppings { get; set; } + public DbSet Toppings { get; set; } + } } diff --git a/exercise.pizzashopapi/Data/Seeder.cs b/exercise.pizzashopapi/Data/Seeder.cs index f87fbef..b0ebb55 100644 --- a/exercise.pizzashopapi/Data/Seeder.cs +++ b/exercise.pizzashopapi/Data/Seeder.cs @@ -1,4 +1,5 @@ -using exercise.pizzashopapi.Models; +using api_cinema_challenge.Models; +using exercise.pizzashopapi.Models; namespace exercise.pizzashopapi.Data { @@ -21,9 +22,32 @@ public async static void SeedPizzaShopApi(this WebApplication app) await db.SaveChangesAsync(); } + if (!db.Orders.Any()) + { + db.Add(new Order() { customerId=1, pizzaId=1 , status="On the road"}); + db.Add(new Order() { customerId = 2, pizzaId = 2 , status="prepearing"}); + await db.SaveChangesAsync(); + + } + if (!db.Toppings.Any()) + { + db.Add(new Topping() { topping = "galic sauce" }); + db.Add(new Topping() { topping = "fish" }); + await db.SaveChangesAsync(); + + } + if (!db.OrderToppings.Any()) + { + db.Add(new OrderToppings() { orderId=1, toppingId=1 }); + db.Add(new OrderToppings() { orderId = 2, toppingId = 2 }); + await db.SaveChangesAsync(); + + } + + //order data - if(1==1) + if (1==1) { await db.SaveChangesAsync(); diff --git a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs index f8be2b0..083092c 100644 --- a/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs +++ b/exercise.pizzashopapi/EndPoints/PizzaShopApi.cs @@ -1,4 +1,8 @@ -using exercise.pizzashopapi.Repository; +using api_cinema_challenge.Models; +using System.ComponentModel.DataAnnotations.Schema; +using exercise.pizzashopapi.DTO; +using exercise.pizzashopapi.Models; +using exercise.pizzashopapi.Repository; using Microsoft.AspNetCore.Mvc; namespace exercise.pizzashopapi.EndPoints @@ -7,9 +11,129 @@ public static class PizzaShopApi { public static void ConfigurePizzaShopApi(this WebApplication app) { - + var pizzaGroup = app.MapGroup("pizzashop"); + + //gets + pizzaGroup.MapGet("/GetOrdersByCustomer", GetOrdersByCustomer); + pizzaGroup.MapGet("/Orders", GetOrders); + pizzaGroup.MapGet("/GetPizzas", GetPizzas); + pizzaGroup.MapGet("/Customers", GetCustomers); + pizzaGroup.MapGet("/Customer", GetCustomer); + //sets + pizzaGroup.MapPut("/Order/status", SetOrderStatus); + //creates + pizzaGroup.MapPost("/neworder", CreateOrder); + pizzaGroup.MapPost("/newcustomer", CreateCustomer); + pizzaGroup.MapPost("/newpizza", CreatePizza); + + } + + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public static async Task CreateOrder(IRepository repo, int customerId, int pizzaId, string status ) + { + try + { + Order order = new Order { status = status , customerId= customerId, pizzaId=pizzaId}; + repo.Insert(order); + repo.Save(); + return TypedResults.Ok(); + } + catch (Exception ex) + { + return TypedResults.BadRequest(ex); + } + } + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public static async Task CreatePizza(IRepository repo, decimal price, string name) + { + try + { + Pizza pizza = new Pizza { Price=price, Name=name}; + repo.Insert(pizza); + repo.Save(); + return TypedResults.Ok(); + } + catch (Exception ex) + { + return TypedResults.BadRequest(ex); + } + } + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public static async Task CreateCustomer(IRepository repo, string name) + { + try + { + Customer customer = new Customer { Name=name }; + repo.Insert(customer); + repo.Save(); + return TypedResults.Ok(); + } + catch (Exception ex) + { + return TypedResults.BadRequest(ex); + } + } + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + public static async Task SetOrderStatus(IRepository repo, int orderId, string status) + { + try + { + Order order = repo.GetById(orderId); + order.status = status; + repo.Save(); + return TypedResults.Ok(); + } + catch (Exception ex) + { + return TypedResults.BadRequest(ex); + } + } + + [ProducesResponseType(StatusCodes.Status200OK)] + public static async Task GetOrdersByCustomer(IRepository repo, int customerId) + { + Customer customer = repo.GetById(customerId); + var orders = customer.Orders.ToList(); + //make it into DTO + List orderDTOs = new List(); + orders.ToList().ForEach(x => orderDTOs.Add(new OrderDTO(x))); + return TypedResults.Ok(orderDTOs); + } + [ProducesResponseType(StatusCodes.Status200OK)] + public static async Task GetOrders(IRepository repo) + { + var orders = repo.GetAll(); + //make it into DTO + List orderDTOs = new List(); + orders.ToList().ForEach(x => orderDTOs.Add(new OrderDTO(x))); + return TypedResults.Ok(orderDTOs); + } + [ProducesResponseType(StatusCodes.Status200OK)] + public static async Task GetPizzas(IRepository repo) + { + var pizzas = repo.GetAll(); + List pizzaDTOs = new List(); + pizzas.ToList().ForEach(x => pizzaDTOs.Add(new PizzaDTO(x))); + return TypedResults.Ok(pizzaDTOs); + } + [ProducesResponseType(StatusCodes.Status200OK)] + public static async Task GetCustomers(IRepository repo) + { + var customers = repo.GetAll(); + List customerDTOs = new List(); + customers.ToList().ForEach( x => customerDTOs.Add(new CustomerDTO(x))); + return TypedResults.Ok(customerDTOs); + } + [ProducesResponseType(StatusCodes.Status200OK)] + public static async Task GetCustomer(IRepository repo ,int id) + { + var customer = repo.GetById(id); + return TypedResults.Ok(new CustomerDTO(customer)); } - } } diff --git a/exercise.pizzashopapi/Migrations/20250128082304_InitialCreate.Designer.cs b/exercise.pizzashopapi/Migrations/20250128082304_InitialCreate.Designer.cs new file mode 100644 index 0000000..f54d09c --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250128082304_InitialCreate.Designer.cs @@ -0,0 +1,126 @@ +// +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("20250128082304_InitialCreate")] + partial class InitialCreate + { + /// + 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") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Name"); + + b.HasKey("Id"); + + b.ToTable("Customer"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("customerId") + .HasColumnType("integer") + .HasColumnName("CustomerId"); + + b.Property("pizzaId") + .HasColumnType("integer") + .HasColumnName("PizzaId"); + + b.HasKey("Id"); + + b.HasIndex("customerId"); + + b.HasIndex("pizzaId"); + + b.ToTable("Order"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Name"); + + b.Property("Price") + .HasColumnType("numeric") + .HasColumnName("Price"); + + b.HasKey("Id"); + + b.ToTable("Pizza"); + }); + + 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/20250128082304_InitialCreate.cs b/exercise.pizzashopapi/Migrations/20250128082304_InitialCreate.cs new file mode 100644 index 0000000..7841350 --- /dev/null +++ b/exercise.pizzashopapi/Migrations/20250128082304_InitialCreate.cs @@ -0,0 +1,91 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace exercise.pizzashopapi.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Customer", + 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_Customer", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Pizza", + 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_Pizza", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Order", + columns: table => new + { + Id = 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_Order", x => x.Id); + table.ForeignKey( + name: "FK_Order_Customer_CustomerId", + column: x => x.CustomerId, + principalTable: "Customer", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Order_Pizza_PizzaId", + column: x => x.PizzaId, + principalTable: "Pizza", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Order_CustomerId", + table: "Order", + column: "CustomerId"); + + migrationBuilder.CreateIndex( + name: "IX_Order_PizzaId", + table: "Order", + column: "PizzaId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Order"); + + migrationBuilder.DropTable( + name: "Customer"); + + migrationBuilder.DropTable( + name: "Pizza"); + } + } +} diff --git a/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs new file mode 100644 index 0000000..d1e119f --- /dev/null +++ b/exercise.pizzashopapi/Migrations/DataContextModelSnapshot.cs @@ -0,0 +1,123 @@ +// +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") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Name"); + + b.HasKey("Id"); + + b.ToTable("Customer"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("customerId") + .HasColumnType("integer") + .HasColumnName("CustomerId"); + + b.Property("pizzaId") + .HasColumnType("integer") + .HasColumnName("PizzaId"); + + b.HasKey("Id"); + + b.HasIndex("customerId"); + + b.HasIndex("pizzaId"); + + b.ToTable("Order"); + }); + + modelBuilder.Entity("exercise.pizzashopapi.Models.Pizza", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasColumnName("Id"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasColumnName("Name"); + + b.Property("Price") + .HasColumnType("numeric") + .HasColumnName("Price"); + + b.HasKey("Id"); + + b.ToTable("Pizza"); + }); + + 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..4e1f02b 100644 --- a/exercise.pizzashopapi/Models/Customer.cs +++ b/exercise.pizzashopapi/Models/Customer.cs @@ -1,10 +1,18 @@ using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Models { + [Table("Customer")] + [PrimaryKey("customerId")] public class Customer { - public int Id { get; set; } + [Column("customerId")] + public int customerId { get; set; } + [Column("Name")] public string Name { get; set; } + [Column("Orders")] + public virtual List Orders { get; set; } = new List(); + } } diff --git a/exercise.pizzashopapi/Models/Order.cs b/exercise.pizzashopapi/Models/Order.cs index fbe6113..232b393 100644 --- a/exercise.pizzashopapi/Models/Order.cs +++ b/exercise.pizzashopapi/Models/Order.cs @@ -1,10 +1,26 @@ using System.ComponentModel.DataAnnotations.Schema; +using api_cinema_challenge.Models; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Models { + [Table("Order")] + [PrimaryKey("orderId")] public class Order { - - + [Column("orderId")] + public int orderId { get; set; } + [Column("Customer")] + public virtual Customer customer { get; set; } + [Column("CustomerId")] + public int customerId { get; set; } + [Column("PizzaId")] + public int pizzaId { get; set; } + [Column("Pizzas")] + public virtual Pizza pizza { get; set; } + [NotMapped] + public virtual List OrderToppings { get; set; } + [Column("status")] + public string status { get; set; } } } diff --git a/exercise.pizzashopapi/Models/OrderToppings.cs b/exercise.pizzashopapi/Models/OrderToppings.cs new file mode 100644 index 0000000..97fc6e9 --- /dev/null +++ b/exercise.pizzashopapi/Models/OrderToppings.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations.Schema; +using exercise.pizzashopapi.Models; +using Microsoft.EntityFrameworkCore; + +namespace api_cinema_challenge.Models +{ + [Table("OrderToppings")] + [PrimaryKey("orderToppingId")] + public class OrderToppings + { + [Column("orderToppingId")] + public int orderToppingId { get; set; } + [Column("orderId")] + public int orderId { get; set; } + [NotMapped] + public virtual Order order { get; set; } + [Column("toppingId")] + public int toppingId { get; set; } + [NotMapped] + public virtual Topping topping { get; set; } + } +} diff --git a/exercise.pizzashopapi/Models/Pizza.cs b/exercise.pizzashopapi/Models/Pizza.cs index 5c085ec..8d02d45 100644 --- a/exercise.pizzashopapi/Models/Pizza.cs +++ b/exercise.pizzashopapi/Models/Pizza.cs @@ -1,12 +1,20 @@ using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Models { - + [Table("Pizza")] + [PrimaryKey("pizzaId")] public class Pizza - { - public int Id { get; set; } + { + [Column("pizzaId")] + public int pizzaId { get; set; } + [Column("Name")] public string Name { get; set; } + [Column("Price")] public decimal Price { get; set; } + + [NotMapped] + public virtual List Orders { get; set; } = new List(); } } \ No newline at end of file diff --git a/exercise.pizzashopapi/Models/Topping.cs b/exercise.pizzashopapi/Models/Topping.cs new file mode 100644 index 0000000..038aa87 --- /dev/null +++ b/exercise.pizzashopapi/Models/Topping.cs @@ -0,0 +1,19 @@ + + +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; + +namespace api_cinema_challenge.Models +{ + [Table("Topping")] + [PrimaryKey("toppingId")] + public class Topping + { + [Column("toppingId")] + public int toppingId { get; set; } + [Column("topping")] + public string topping { get; set; } + [Column("orderToppings")] + public virtual List orderToppings { get; set; } + } +} diff --git a/exercise.pizzashopapi/Program.cs b/exercise.pizzashopapi/Program.cs index c04a440..bc33dcf 100644 --- a/exercise.pizzashopapi/Program.cs +++ b/exercise.pizzashopapi/Program.cs @@ -1,5 +1,6 @@ using exercise.pizzashopapi.Data; using exercise.pizzashopapi.EndPoints; +using exercise.pizzashopapi.Models; using exercise.pizzashopapi.Repository; var builder = WebApplication.CreateBuilder(args); @@ -7,7 +8,9 @@ // Add services to the container. builder.Services.AddControllers(); -builder.Services.AddScoped(); +builder.Services.AddScoped, Repository>(); +builder.Services.AddScoped, Repository>(); +builder.Services.AddScoped, Repository>(); builder.Services.AddDbContext(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); diff --git a/exercise.pizzashopapi/Repository/IRepository.cs b/exercise.pizzashopapi/Repository/IRepository.cs index b114ea8..021373a 100644 --- a/exercise.pizzashopapi/Repository/IRepository.cs +++ b/exercise.pizzashopapi/Repository/IRepository.cs @@ -1,11 +1,19 @@ -using exercise.pizzashopapi.Models; +using System.Linq.Expressions; +using exercise.pizzashopapi.Models; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Repository { - public interface IRepository + public interface IRepository where T : class { - Task> GetOrdersByCustomer(int id); - + public IEnumerable GetAll(); + IEnumerable GetAll(params Expression>[] includeExpressions); + T GetById(object id); + void Insert(T obj); + void Update(T obj); + void Delete(object id); + void Save(); + DbSet Table { get; } } } diff --git a/exercise.pizzashopapi/Repository/Repository.cs b/exercise.pizzashopapi/Repository/Repository.cs index e109fce..2e0d995 100644 --- a/exercise.pizzashopapi/Repository/Repository.cs +++ b/exercise.pizzashopapi/Repository/Repository.cs @@ -1,14 +1,65 @@ -using exercise.pizzashopapi.Data; +using System.Linq.Expressions; +using exercise.pizzashopapi.Data; using exercise.pizzashopapi.Models; +using Microsoft.EntityFrameworkCore; namespace exercise.pizzashopapi.Repository { - public class Repository : IRepository + public class Repository : IRepository where T : class { + + private DataContext _db; - public Task> GetOrdersByCustomer(int id) + private DbSet _table = null; + + public Repository(DataContext db) + { + _db = db; + _table = _db.Set(); + } + + public IEnumerable GetAll(params Expression>[] includeExpressions) + { + if (includeExpressions.Any()) + { + var set = includeExpressions + .Aggregate>, IQueryable> + (_table, (current, expression) => current.Include(expression)); + } + return _table.ToList(); + } + + public IEnumerable GetAll() + { + return _table.ToList(); + } + public T GetById(object id) + { + return _table.Find(id); + } + + public void Insert(T obj) + { + _table.Add(obj); + } + public void Update(T obj) + { + _table.Attach(obj); + _db.Entry(obj).State = EntityState.Modified; + } + + public void Delete(object id) + { + T existing = _table.Find(id); + _table.Remove(existing); + } + + + public void Save() { - throw new NotImplementedException(); + _db.SaveChanges(); } + public DbSet Table { get { return _table; } } + } } diff --git a/exercise.pizzashopapi/exercise.pizzashopapi.csproj b/exercise.pizzashopapi/exercise.pizzashopapi.csproj index 624203b..98892e1 100644 --- a/exercise.pizzashopapi/exercise.pizzashopapi.csproj +++ b/exercise.pizzashopapi/exercise.pizzashopapi.csproj @@ -1,28 +1,31 @@ - - net9.0 - enable - enable - + + net9.0 + enable + enable + api_cinema_challenge + - - - + + + + + + - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + - + \ No newline at end of file