diff --git a/BookShop/BookShop.sln b/BookShop/BookShop.sln index cbefac8..cac5eff 100644 --- a/BookShop/BookShop.sln +++ b/BookShop/BookShop.sln @@ -3,9 +3,15 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33530.505 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookShopView", "BookShopView\BookShopView.csproj", "{1455C2BC-5C22-4B93-8954-ACC01353BD24}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookShopView", "BookShopView\BookShopView.csproj", "{1455C2BC-5C22-4B93-8954-ACC01353BD24}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookShopDataModels", "BookShopDataModels\BookShopDataModels.csproj", "{032BDFC0-6AAF-4A75-A9AE-B24C85A4679C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookShopDataModels", "BookShopDataModels\BookShopDataModels.csproj", "{032BDFC0-6AAF-4A75-A9AE-B24C85A4679C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookShopContracts", "BookShopContracts\BookShopContracts.csproj", "{0F724A0C-BAE5-4784-A7C5-FCCF7BE07EA5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookShopBusinessLogic", "BookShopBusinessLogic\BookShopBusinessLogic.csproj", "{CA4B49FE-3671-4440-9E06-9B5F8D0CDB58}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookShopDataBaseImplement", "BookShopDataBaseImplement\BookShopDataBaseImplement.csproj", "{EF559D7F-C94F-4F76-833E-44DF7FEDEDBD}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +27,18 @@ Global {032BDFC0-6AAF-4A75-A9AE-B24C85A4679C}.Debug|Any CPU.Build.0 = Debug|Any CPU {032BDFC0-6AAF-4A75-A9AE-B24C85A4679C}.Release|Any CPU.ActiveCfg = Release|Any CPU {032BDFC0-6AAF-4A75-A9AE-B24C85A4679C}.Release|Any CPU.Build.0 = Release|Any CPU + {0F724A0C-BAE5-4784-A7C5-FCCF7BE07EA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F724A0C-BAE5-4784-A7C5-FCCF7BE07EA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F724A0C-BAE5-4784-A7C5-FCCF7BE07EA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F724A0C-BAE5-4784-A7C5-FCCF7BE07EA5}.Release|Any CPU.Build.0 = Release|Any CPU + {CA4B49FE-3671-4440-9E06-9B5F8D0CDB58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA4B49FE-3671-4440-9E06-9B5F8D0CDB58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA4B49FE-3671-4440-9E06-9B5F8D0CDB58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA4B49FE-3671-4440-9E06-9B5F8D0CDB58}.Release|Any CPU.Build.0 = Release|Any CPU + {EF559D7F-C94F-4F76-833E-44DF7FEDEDBD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF559D7F-C94F-4F76-833E-44DF7FEDEDBD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF559D7F-C94F-4F76-833E-44DF7FEDEDBD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF559D7F-C94F-4F76-833E-44DF7FEDEDBD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/BookShop/BookShopBusinessLogic/BookShopBusinessLogic.csproj b/BookShop/BookShopBusinessLogic/BookShopBusinessLogic.csproj index 132c02c..40ad81a 100644 --- a/BookShop/BookShopBusinessLogic/BookShopBusinessLogic.csproj +++ b/BookShop/BookShopBusinessLogic/BookShopBusinessLogic.csproj @@ -6,4 +6,12 @@ enable + + + + + + + + diff --git a/BookShop/BookShopContracts/BookShopContracts.csproj b/BookShop/BookShopContracts/BookShopContracts.csproj index 132c02c..cec9677 100644 --- a/BookShop/BookShopContracts/BookShopContracts.csproj +++ b/BookShop/BookShopContracts/BookShopContracts.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/BookShop/BookShopDataBaseImplement/BookShopDataBaseImplement.csproj b/BookShop/BookShopDataBaseImplement/BookShopDataBaseImplement.csproj new file mode 100644 index 0000000..f9d44cf --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/BookShopDataBaseImplement.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/BookShop/BookShopDataBaseImplement/BookShopDatabase.cs b/BookShop/BookShopDataBaseImplement/BookShopDatabase.cs new file mode 100644 index 0000000..c8be76a --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/BookShopDatabase.cs @@ -0,0 +1,23 @@ +using BookShopDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace BookShopDataBaseImplement +{ + public class BookShopDatabase : DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseNpgsql(@"Host=192.168.56.101;Port=5432;Database=SUBD_Lab2;Username=postgres;Password=postgres"); + } + base.OnConfiguring(optionsBuilder); + } + public virtual DbSet Authors { set; get; } + public virtual DbSet Books { set; get; } + public virtual DbSet BookAuthors { set; get; } + public virtual DbSet Orders { set; get; } + public virtual DbSet Clients { set; get; } + public virtual DbSet Genres { set; get; } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Implements/AuthorStorage.cs b/BookShop/BookShopDataBaseImplement/Implements/AuthorStorage.cs new file mode 100644 index 0000000..774b108 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Implements/AuthorStorage.cs @@ -0,0 +1,76 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.SearchModels; +using BookShopContracts.StoragesContracts; +using BookShopContracts.ViewModels; +using BookShopDataBaseImplement.Models; + +namespace BookShopDataBaseImplement.Implements +{ + public class AuthorStorage : IAuthorStorage + { + public AuthorViewModel? Delete(AuthorBindingModel model) + { + using var context = new BookShopDatabase(); + var element = context.Authors.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Authors.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public AuthorViewModel? GetElement(AuthorSearchModel model) + { + using var context = new BookShopDatabase(); + if (model.Id.HasValue) + return context.Authors.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; + if (!string.IsNullOrEmpty(model.AuthorSurname)) + return context.Authors.FirstOrDefault(x => x.AuthorSurname.Equals(model.AuthorSurname))?.GetViewModel; + return null; + } + + public List GetFilteredList(AuthorSearchModel model) + { + if (string.IsNullOrEmpty(model.AuthorSurname)) + { + return new(); + } + using var context = new BookShopDatabase(); + return context.Authors.Where(x => x.AuthorSurname.Contains(model.AuthorSurname)).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new BookShopDatabase(); + return context.Authors.Select(x => x.GetViewModel).ToList(); + } + + public AuthorViewModel? Insert(AuthorBindingModel model) + { + var newAuthor = Author.Create(model); + if (newAuthor == null) + { + return null; + } + using var context = new BookShopDatabase(); + context.Authors.Add(newAuthor); + context.SaveChanges(); + return newAuthor.GetViewModel; + } + + public AuthorViewModel? Update(AuthorBindingModel model) + { + using var context = new BookShopDatabase(); + var client = context.Authors.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + client.Update(model); + context.SaveChanges(); + return client.GetViewModel; + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Implements/BookStorage.cs b/BookShop/BookShopDataBaseImplement/Implements/BookStorage.cs new file mode 100644 index 0000000..1196e07 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Implements/BookStorage.cs @@ -0,0 +1,137 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.SearchModels; +using BookShopContracts.StoragesContracts; +using BookShopContracts.ViewModels; +using BookShopDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System.Diagnostics; + +namespace BookShopDataBaseImplement.Implements +{ + public class BookStorage : IBookStorage + { + public List GetFullList() + { + using var context = new BookShopDatabase(); + return context.Books + .Include(x => x.Genre) + .Include(x => x.Authors) + .ThenInclude(x => x.Author) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(BookSearchModel model) + { + if (string.IsNullOrEmpty(model.BookName)) + { + return new(); + } + using var context = new BookShopDatabase(); + return context.Books + .Include(x => x.Authors) + .ThenInclude(x => x.Author) + .Where(x => x.BookName.Contains(model.BookName)) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + public BookViewModel? GetElement(BookSearchModel model) + { + if (string.IsNullOrEmpty(model.BookName) && + !model.Id.HasValue) + { + return null; + } + using var context = new BookShopDatabase(); + return context.Books + .Include(x => x.Authors) + .ThenInclude(x => x.Author) + .FirstOrDefault(x => (!string.IsNullOrEmpty(model.BookName) && + x.BookName == model.BookName) || + (model.Id.HasValue && x.Id == + model.Id)) + ?.GetViewModel; + } + public BookViewModel? Insert(BookBindingModel model) + { + using var context = new BookShopDatabase(); + var newBook = Book.Create(context, model); + if (newBook == null) + { + return null; + } + context.Books.Add(newBook); + context.SaveChanges(); + return newBook.GetViewModel; + } + public BookViewModel? Update(BookBindingModel model) + { + using var context = new BookShopDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var book = context.Books.FirstOrDefault(rec => + rec.Id == model.Id); + if (book == null) + { + return null; + } + book.Update(model); + context.SaveChanges(); + book.UpdateAuthors(context, model); + transaction.Commit(); + return book.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + public BookViewModel? Delete(BookBindingModel model) + { + using var context = new BookShopDatabase(); + var element = context.Books + .Include(x => x.GenreId) + .Include(x => x.Authors) + .FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Books.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + public string TestInsertList(int num) + { + throw new NotImplementedException(); + } + + public string TestReadList(int num) + { + var context = new BookShopDatabase(); + Stopwatch stopwatch = new(); + + long[] res = new long[num]; + + for (int i = 0; i < num; i++) + { + + stopwatch.Start(); + List list = context.Books.Include(x => x.Genre).Include(x => x.Authors).ThenInclude(x => x.Author).ToList().Select(x => x.GetViewModel).ToList(); + stopwatch.Stop(); + res[i] = stopwatch.ElapsedMilliseconds; + } + + long sum = 0; + for (int i = 0; i < num; i++) + { + sum += res[i]; + } + int result = Convert.ToInt32(sum / num); + return result.ToString(); + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Implements/ClientStorage.cs b/BookShop/BookShopDataBaseImplement/Implements/ClientStorage.cs new file mode 100644 index 0000000..2ffb529 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Implements/ClientStorage.cs @@ -0,0 +1,76 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.SearchModels; +using BookShopContracts.StoragesContracts; +using BookShopContracts.ViewModels; +using BookShopDataBaseImplement.Models; + +namespace BookShopDataBaseImplement.Implements +{ + public class ClientStorage : IClientStorage + { + public ClientViewModel? Delete(ClientBindingModel model) + { + using var context = new BookShopDatabase(); + var element = context.Clients.FirstOrDefault(rec => rec.Id == model.Id); + if (element != null) + { + context.Clients.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + + public ClientViewModel? GetElement(ClientSearchModel model) + { + using var context = new BookShopDatabase(); + if (model.Id.HasValue) + return context.Clients.FirstOrDefault(x => x.Id == model.Id)?.GetViewModel; + if (!string.IsNullOrEmpty(model.Email)) + return context.Clients.FirstOrDefault(x => x.Email.Equals(model.Email))?.GetViewModel; + return null; + } + + public List GetFilteredList(ClientSearchModel model) + { + if (string.IsNullOrEmpty(model.ClientSurname)) + { + return new(); + } + using var context = new BookShopDatabase(); + return context.Clients.Where(x => x.ClientSurname.Contains(model.ClientSurname)).Select(x => x.GetViewModel).ToList(); + } + + public List GetFullList() + { + using var context = new BookShopDatabase(); + return context.Clients.Select(x => x.GetViewModel).ToList(); + } + + public ClientViewModel? Insert(ClientBindingModel model) + { + var newClient = Client.Create(model); + if (newClient == null) + { + return null; + } + using var context = new BookShopDatabase(); + context.Clients.Add(newClient); + context.SaveChanges(); + return newClient.GetViewModel; + } + + public ClientViewModel? Update(ClientBindingModel model) + { + using var context = new BookShopDatabase(); + var client = context.Clients.FirstOrDefault(x => x.Id == model.Id); + if (client == null) + { + return null; + } + client.Update(model); + context.SaveChanges(); + return client.GetViewModel; + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Implements/GenreStorage.cs b/BookShop/BookShopDataBaseImplement/Implements/GenreStorage.cs new file mode 100644 index 0000000..1c7f7db --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Implements/GenreStorage.cs @@ -0,0 +1,86 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.SearchModels; +using BookShopContracts.StoragesContracts; +using BookShopContracts.ViewModels; +using BookShopDataBaseImplement.Models; +using BookShopDataModels.Models; +using System.ComponentModel; + +namespace BookShopDataBaseImplement.Implements +{ + public class GenreStorage : IGenreStorage + { + public List GetFullList() + { + using var context = new BookShopDatabase(); + return context.Genres + .Select(x => x.GetViewModel) + .ToList(); + } + public List GetFilteredList(GenreSearchModel + model) + { + if (string.IsNullOrEmpty(model.GenreName)) + { + return new(); + } + using var context = new BookShopDatabase(); + return context.Genres + .Where(x => x.GenreName.Contains(model.GenreName)) + .Select(x => x.GetViewModel) + .ToList(); + } + public GenreViewModel? GetElement(GenreSearchModel model) + { + if (string.IsNullOrEmpty(model.GenreName) && !model.Id.HasValue) + { + return null; + } + using var context = new BookShopDatabase(); + return context.Genres + .FirstOrDefault(x => + (!string.IsNullOrEmpty(model.GenreName) && x.GenreName == + model.GenreName) || + (model.Id.HasValue && x.Id == model.Id)) + ?.GetViewModel; + } + public GenreViewModel? Insert(GenreBindingModel model) + { + var newGenre = Genre.Create(model); + if (newGenre == null) + { + return null; + } + using var context = new BookShopDatabase(); + context.Genres.Add(newGenre); + context.SaveChanges(); + return newGenre.GetViewModel; + } + public GenreViewModel? Update(GenreBindingModel model) + { + using var context = new BookShopDatabase(); + var genre = context.Genres.FirstOrDefault(x => x.Id == + model.Id); + if (genre == null) + { + return null; + } + genre.Update(model); + context.SaveChanges(); + return genre.GetViewModel; + } + public GenreViewModel? Delete(GenreBindingModel model) + { + using var context = new BookShopDatabase(); + var element = context.Genres.FirstOrDefault(rec => rec.Id == + model.Id); + if (element != null) + { + context.Genres.Remove(element); + context.SaveChanges(); + return element.GetViewModel; + } + return null; + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Implements/OrderStorage.cs b/BookShop/BookShopDataBaseImplement/Implements/OrderStorage.cs new file mode 100644 index 0000000..99250be --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Implements/OrderStorage.cs @@ -0,0 +1,103 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.SearchModels; +using BookShopContracts.StoragesContracts; +using BookShopContracts.ViewModels; +using BookShopDataBaseImplement.Models; +using Microsoft.EntityFrameworkCore; + +namespace BookShopDataBaseImplement.Implements +{ + public class OrderStorage : IOrderStorage + { + public OrderViewModel? Delete(OrderBindingModel model) + { + using var context = new BookShopDatabase(); + + var element = context.Orders.Include(x => x.Book) + .Include(x => x.Client).FirstOrDefault(rec => rec.Id == model.Id); + + if (element != null) + { + context.Orders.Remove(element); + context.SaveChanges(); + + return element.GetViewModel; + } + + return null; + } + + public OrderViewModel? GetElement(OrderSearchModel model) + { + if (!model.Id.HasValue) + { + return null; + } + using var context = new BookShopDatabase(); + return context.Orders + .FirstOrDefault(x => model.Id.HasValue && x.Id == model.Id) + ?.GetViewModel; + } + + public List GetFilteredList(OrderSearchModel model) + { + if (model is null) + { + return new(); + } + using var context = new BookShopDatabase(); + return context.Orders + .Where(x => x.ClientId == model.ClientId) + .ToList() + .Select(x => x.GetViewModel) + .ToList(); + } + + public List GetFullList() + { + using var context = new BookShopDatabase(); + + return context.Orders.Include(x => x.Book) + .Include(x => x.Client).Select(x => x.GetViewModel).ToList(); + } + + public OrderViewModel? Insert(OrderBindingModel model) + { + var newOrder = Order.Create(model); + + if (newOrder == null) + { + return null; + } + + using var context = new BookShopDatabase(); + + context.Orders.Add(newOrder); + context.SaveChanges(); + + return context.Orders + .Include(x => x.Book) + .Include(x => x.Client) + .FirstOrDefault(x => x.Id == newOrder.Id) + ?.GetViewModel; + } + + public OrderViewModel? Update(OrderBindingModel model) + { + using var context = new BookShopDatabase(); + + var order = context.Orders.Include(x => x.Book) + .Include(x => x.Client).FirstOrDefault(x => x.Id == model.Id); + + if (order == null) + { + return null; + } + + order.Update(model); + context.SaveChanges(); + + return order.GetViewModel; + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.Designer.cs b/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.Designer.cs new file mode 100644 index 0000000..3bc2ca4 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.Designer.cs @@ -0,0 +1,255 @@ +// +using System; +using BookShopDataBaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BookShopDataBaseImplement.Migrations +{ + [DbContext(typeof(BookShopDatabase))] + [Migration("20230512083316_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorName") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuthorPatronymic") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuthorSurname") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BookName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("GenreId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GenreId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.BookAuthor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorId") + .HasColumnType("integer"); + + b.Property("BookId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("BookId"); + + b.ToTable("BookAuthors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientPatronymic") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientSurname") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GenreName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Genres"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BookId") + .HasColumnType("integer"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp with time zone"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("BookId"); + + b.HasIndex("ClientId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Genre", "Genre") + .WithMany("Books") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.BookAuthor", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Author", "Author") + .WithMany("BookAuthors") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookShopDataBaseImplement.Models.Book", "Book") + .WithMany("Authors") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Book"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Order", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Book", "Book") + .WithMany("Orders") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookShopDataBaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Author", b => + { + b.Navigation("BookAuthors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.Navigation("Authors"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Genre", b => + { + b.Navigation("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.cs b/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.cs new file mode 100644 index 0000000..14cec87 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Migrations/20230512083316_Initial.cs @@ -0,0 +1,184 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BookShopDataBaseImplement.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Authors", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + AuthorSurname = table.Column(type: "text", nullable: false), + AuthorName = table.Column(type: "text", nullable: false), + AuthorPatronymic = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Authors", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ClientSurname = table.Column(type: "text", nullable: false), + ClientName = table.Column(type: "text", nullable: false), + ClientPatronymic = table.Column(type: "text", nullable: false), + Email = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Genres", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + GenreName = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Genres", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Books", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + BookName = table.Column(type: "text", nullable: false), + Count = table.Column(type: "integer", nullable: false), + Cost = table.Column(type: "double precision", nullable: false), + GenreId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Books", x => x.Id); + table.ForeignKey( + name: "FK_Books_Genres_GenreId", + column: x => x.GenreId, + principalTable: "Genres", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BookAuthors", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + BookId = table.Column(type: "integer", nullable: false), + AuthorId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BookAuthors", x => x.Id); + table.ForeignKey( + name: "FK_BookAuthors_Authors_AuthorId", + column: x => x.AuthorId, + principalTable: "Authors", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_BookAuthors_Books_BookId", + column: x => x.BookId, + principalTable: "Books", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + BookId = table.Column(type: "integer", nullable: false), + ClientId = table.Column(type: "integer", nullable: false), + Count = table.Column(type: "integer", nullable: false), + Sum = table.Column(type: "double precision", nullable: false), + DateCreate = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + table.ForeignKey( + name: "FK_Orders_Books_BookId", + column: x => x.BookId, + principalTable: "Books", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Orders_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_BookAuthors_AuthorId", + table: "BookAuthors", + column: "AuthorId"); + + migrationBuilder.CreateIndex( + name: "IX_BookAuthors_BookId", + table: "BookAuthors", + column: "BookId"); + + migrationBuilder.CreateIndex( + name: "IX_Books_GenreId", + table: "Books", + column: "GenreId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BookId", + table: "Orders", + column: "BookId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_ClientId", + table: "Orders", + column: "ClientId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BookAuthors"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Authors"); + + migrationBuilder.DropTable( + name: "Books"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "Genres"); + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Migrations/BookShopDatabaseModelSnapshot.cs b/BookShop/BookShopDataBaseImplement/Migrations/BookShopDatabaseModelSnapshot.cs new file mode 100644 index 0000000..6f65062 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Migrations/BookShopDatabaseModelSnapshot.cs @@ -0,0 +1,252 @@ +// +using System; +using BookShopDataBaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace BookShopDataBaseImplement.Migrations +{ + [DbContext(typeof(BookShopDatabase))] + partial class BookShopDatabaseModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorName") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuthorPatronymic") + .IsRequired() + .HasColumnType("text"); + + b.Property("AuthorSurname") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BookName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Cost") + .HasColumnType("double precision"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("GenreId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GenreId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.BookAuthor", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AuthorId") + .HasColumnType("integer"); + + b.Property("BookId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("BookId"); + + b.ToTable("BookAuthors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientName") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientPatronymic") + .IsRequired() + .HasColumnType("text"); + + b.Property("ClientSurname") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Genre", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GenreName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Genres"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BookId") + .HasColumnType("integer"); + + b.Property("ClientId") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("DateCreate") + .HasColumnType("timestamp with time zone"); + + b.Property("Sum") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("BookId"); + + b.HasIndex("ClientId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Genre", "Genre") + .WithMany("Books") + .HasForeignKey("GenreId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Genre"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.BookAuthor", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Author", "Author") + .WithMany("BookAuthors") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookShopDataBaseImplement.Models.Book", "Book") + .WithMany("Authors") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Book"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Order", b => + { + b.HasOne("BookShopDataBaseImplement.Models.Book", "Book") + .WithMany("Orders") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("BookShopDataBaseImplement.Models.Client", "Client") + .WithMany("Orders") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Client"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Author", b => + { + b.Navigation("BookAuthors"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Book", b => + { + b.Navigation("Authors"); + + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Client", b => + { + b.Navigation("Orders"); + }); + + modelBuilder.Entity("BookShopDataBaseImplement.Models.Genre", b => + { + b.Navigation("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/Author.cs b/BookShop/BookShopDataBaseImplement/Models/Author.cs new file mode 100644 index 0000000..e0913ec --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/Author.cs @@ -0,0 +1,63 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.ViewModels; +using BookShopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace BookShopDataBaseImplement.Models +{ + public class Author : IAuthorModel + { + public int Id { get; private set; } + [Required] + public string AuthorSurname { get; set; } = string.Empty; + [Required] + public string AuthorName { get; set; } = string.Empty; + [Required] + public string AuthorPatronymic { get; set; } = string.Empty; + + [ForeignKey("AuthorId")] + public virtual List BookAuthors { get; set; } = new(); + public static Author? Create(AuthorBindingModel model) + { + if (model == null) + { + return null; + } + return new Author() + { + Id = model.Id, + AuthorSurname = model.AuthorSurname, + AuthorName = model.AuthorName, + AuthorPatronymic = model.AuthorPatronymic + }; + } + public static Author Create(AuthorViewModel model) + { + return new Author + { + Id = model.Id, + AuthorSurname = model.AuthorSurname, + AuthorName = model.AuthorName, + AuthorPatronymic = model.AuthorPatronymic + }; + } + public void Update(AuthorBindingModel model) + { + if (model == null) + { + return; + } + AuthorSurname = model.AuthorSurname; + AuthorName = model.AuthorName; + AuthorPatronymic = model.AuthorPatronymic; + } + public AuthorViewModel GetViewModel => new() + { + Id = Id, + AuthorSurname = AuthorSurname, + AuthorName = AuthorName, + AuthorPatronymic = AuthorPatronymic + }; + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/Book.cs b/BookShop/BookShopDataBaseImplement/Models/Book.cs new file mode 100644 index 0000000..5e2df94 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/Book.cs @@ -0,0 +1,108 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.ViewModels; +using BookShopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; + +namespace BookShopDataBaseImplement.Models +{ + public class Book : IBookModel + { + public int Id { get; private set; } + [Required] + public string BookName { get; set; } = string.Empty; + [Required] + public int Count { get; set; } + [Required] + public double Cost { get; set; } + [Required] + public int GenreId { get; set; } + public virtual Genre Genre { get; set; } + private Dictionary? _bookAuthors = null; + [NotMapped] + public Dictionary BookAuthors + { + get + { + if (_bookAuthors == null) + { + _bookAuthors = Authors.ToDictionary(recPC => recPC.AuthorId, recPC => recPC.Author as IAuthorModel); + } + return _bookAuthors; + } + } + [ForeignKey("BookId")] + public virtual List Authors { get; set; } = new(); + [ForeignKey("BookId")] + public virtual List Orders { get; set; } = new(); + public static Book Create(BookShopDatabase context, BookBindingModel model) + { + return new Book() + { + Id = model.Id, + BookName = model.BookName, + Cost = model.Cost, + Count = model.Count, + GenreId = model.GenreId, + Authors = model.BookAuthors.Select(x => new BookAuthor + { + Author = context.Authors.First(y => y.Id == x.Key) + }).ToList() + }; + } + public void Update(BookBindingModel model) + { + BookName = model.BookName; + Cost = model.Cost; + Cost = model.Cost; + GenreId = model.GenreId; + } + public BookViewModel GetViewModel + { + + get + + { + using var context = new BookShopDatabase(); + return new BookViewModel + { + Id = Id, + BookName = BookName, + Cost = Cost, + GenreId= GenreId, + GenreName = context.Genres.FirstOrDefault(x => x.Id == GenreId)?.GenreName ?? string.Empty, + BookAuthors = BookAuthors +}; + } +} + public void UpdateAuthors(BookShopDatabase context, BookBindingModel model) + { + var bookAuthors = context.BookAuthors.Where(rec => + rec.BookId == model.Id).ToList(); + if (bookAuthors != null && bookAuthors.Count > 0) + { // удалили те, которых нет в модели + context.BookAuthors.RemoveRange(bookAuthors.Where(rec + => !model.BookAuthors.ContainsKey(rec.AuthorId))); + context.SaveChanges(); + // обновили количество у существующих записей + foreach (var updateAuthor in bookAuthors) + { + model.BookAuthors.Remove(updateAuthor.AuthorId); + } + context.SaveChanges(); + } + var book = context.Books.First(x => x.Id == Id); + foreach (var pc in model.BookAuthors) + { + context.BookAuthors.Add(new BookAuthor + { + Book = book, + Author = context.Authors.First(x => x.Id == pc.Key) + }); + context.SaveChanges(); + } + _bookAuthors = null; + } + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/BookAuthor.cs b/BookShop/BookShopDataBaseImplement/Models/BookAuthor.cs new file mode 100644 index 0000000..20ee469 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/BookAuthor.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; + +namespace BookShopDataBaseImplement.Models +{ + public class BookAuthor + { + public int Id { get; set; } + [Required] + public int BookId { get; set; } + [Required] + public int AuthorId { get; set; } + public virtual Book Book { get; set; } = new(); + public virtual Author Author { get; set; } = new(); + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/Client.cs b/BookShop/BookShopDataBaseImplement/Models/Client.cs new file mode 100644 index 0000000..e4bbd83 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/Client.cs @@ -0,0 +1,69 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.ViewModels; +using BookShopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace BookShopDataBaseImplement.Models +{ + public class Client : IClientModel + { + public int Id { get; private set; } + [Required] + public string ClientSurname { get; set; } = string.Empty; + [Required] + public string ClientName { get; set; } = string.Empty; + [Required] + public string ClientPatronymic { get; set; } = string.Empty; + [Required] + public string Email { get; set; } = string.Empty; + + [ForeignKey("ClientId")] + public virtual List Orders { get; set; } = new(); + public static Client? Create(ClientBindingModel model) + { + if (model == null) + { + return null; + } + return new Client() + { + Id = model.Id, + ClientSurname = model.ClientSurname, + ClientName = model.ClientName, + ClientPatronymic = model.ClientPatronymic, + Email = model.Email + }; + } + public static Client Create(ClientViewModel model) + { + return new Client + { + Id = model.Id, + ClientSurname = model.ClientSurname, + ClientName = model.ClientName, + ClientPatronymic = model.ClientPatronymic, + Email = model.Email + }; + } + public void Update(ClientBindingModel model) + { + if (model == null) + { + return; + } + ClientSurname = model.ClientSurname; + ClientName = model.ClientName; + ClientPatronymic = model.ClientPatronymic; + Email = model.Email; + } + public ClientViewModel GetViewModel => new() + { + Id = Id, + ClientSurname = ClientSurname, + ClientName = ClientName, + ClientPatronymic = ClientPatronymic, + Email = Email + }; + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/Genre.cs b/BookShop/BookShopDataBaseImplement/Models/Genre.cs new file mode 100644 index 0000000..fb318cd --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/Genre.cs @@ -0,0 +1,51 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.ViewModels; +using BookShopDataModels.Models; +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace BookShopDataBaseImplement.Models +{ + public class Genre : IGenreModel + { + public int Id { get; private set; } + [Required] + public string GenreName { get; set; } = string.Empty; + + [ForeignKey("GenreId")] + public virtual List Books { get; set; } = new(); + public static Genre? Create(GenreBindingModel model) + { + if (model == null) + { + return null; + } + return new Genre() + { + Id = model.Id, + GenreName = model.GenreName + }; + } + public static Genre Create(GenreViewModel model) + { + return new Genre + { + Id = model.Id, + GenreName = model.GenreName + }; + } + public void Update(GenreBindingModel model) + { + if (model == null) + { + return; + } + GenreName = model.GenreName; + } + public GenreViewModel GetViewModel => new() + { + Id = Id, + GenreName = GenreName + }; + } +} diff --git a/BookShop/BookShopDataBaseImplement/Models/Order.cs b/BookShop/BookShopDataBaseImplement/Models/Order.cs new file mode 100644 index 0000000..363e5b2 --- /dev/null +++ b/BookShop/BookShopDataBaseImplement/Models/Order.cs @@ -0,0 +1,79 @@ +using BookShopContracts.BindingModels; +using BookShopContracts.ViewModels; +using BookShopDataModels.Models; +using System.ComponentModel.DataAnnotations; + +namespace BookShopDataBaseImplement.Models +{ + public class Order : IOrderModel + { + public int Id { get; private set; } + + public int BookId { get; private set; } + [Required] + public int ClientId { get; set; } + + [Required] + public int Count { get; private set; } + + [Required] + public double Sum { get; private set; } + + [Required] + public DateTime DateCreate { get; private set; } = DateTime.Now; + + public virtual Book Book { get; set; } + public Client Client { get; set; } + + public static Order? Create(OrderBindingModel? model) + { + if (model == null) + { + return null; + } + + return new Order() + { + Id = model.Id, + ClientId = model.ClientId, + BookId = model.BookId, + Count = model.Count, + Sum = model.Sum, + DateCreate = model.DateCreate + }; + } + + public void Update(OrderBindingModel? model) + { + if (model == null) + { + return; + } + Id = model.Id; + ClientId = model.ClientId; + BookId = model.BookId; + Count = model.Count; + Sum = model.Sum; + DateCreate = model.DateCreate; + } + + public OrderViewModel GetViewModel + { + get + { + using var context = new BookShopDatabase(); + return new OrderViewModel + { + Id = Id, + ClientId = ClientId, + ClientSurname = context.Clients.FirstOrDefault(x => x.Id == ClientId)?.ClientSurname ?? string.Empty, + BookName = context.Books.FirstOrDefault(x => x.Id == BookId)?.BookName ?? string.Empty, + BookId = BookId, + Count = Count, + Sum = Sum, + DateCreate = DateCreate + }; + } + } + } +} diff --git a/BookShop/BookShopView/BookShopView.csproj b/BookShop/BookShopView/BookShopView.csproj index b57c89e..0162b34 100644 --- a/BookShop/BookShopView/BookShopView.csproj +++ b/BookShop/BookShopView/BookShopView.csproj @@ -8,4 +8,18 @@ enable + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + \ No newline at end of file