diff --git a/BusinessLogic/AuthorLogic.cs b/BusinessLogic/AuthorLogic.cs new file mode 100644 index 0000000..b0766f7 --- /dev/null +++ b/BusinessLogic/AuthorLogic.cs @@ -0,0 +1,65 @@ +using Contracts.BindingModels; +using Contracts.BusinessLogicContracts; +using Contracts.StorageContracts; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BusinessLogic +{ + public class AuthorLogic:IAuthorLogic + { + private readonly IAuthorStorage _authorStorage; + public AuthorLogic(IAuthorStorage authorStorage) + { + _authorStorage = authorStorage; + } + + public void CreateOrUpdate(AuthorBindingModel model) + { + var element = _authorStorage.GetElement( + new AuthorBindingModel + { + FIO = model.FIO + }); + if (element != null && element.Id != model.Id) + { + throw new Exception("Такой автор уже существует"); + } + if (model.Id.HasValue) + { + _authorStorage.Update(model); + } + else + { + _authorStorage.Insert(model); + } + } + + public void Delete(AuthorBindingModel model) + { + var element = _authorStorage.GetElement(new AuthorBindingModel { Id = model.Id }); + if (element == null) + { + throw new Exception("Автор не найден"); + } + _authorStorage.Delete(model); + } + + public List Read(AuthorBindingModel model) + { + if (model == null) + { + return _authorStorage.GetFullList(); + } + if (model.Id.HasValue) + { + return new List { _authorStorage.GetElement(model) }; + } + return _authorStorage.GetFilteredList(model); + } + } +} diff --git a/BusinessLogic/BookLogic.cs b/BusinessLogic/BookLogic.cs new file mode 100644 index 0000000..dc0ebb5 --- /dev/null +++ b/BusinessLogic/BookLogic.cs @@ -0,0 +1,67 @@ +using Contracts.BindingModels; +using Contracts.BusinessLogicContracts; +using Contracts.StorageContracts; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BusinessLogic +{ + public class BookLogic : IBookLogic + { + private readonly IBookStorage _bookStorage; + public BookLogic(IBookStorage bookStorage) + { + _bookStorage = bookStorage; + } + public void CreateOrUpdate(BookBindingModel model) + { + var element = _bookStorage.GetElement( + new BookBindingModel + { + Name = model.Name, + Author = model.Author, + PicturePath = model.PicturePath, + PublicationDate = model.PublicationDate + }); + if (element != null && element.Id != model.Id) + { + throw new Exception("Книга с таким названием уже существует"); + } + if (model.Id.HasValue) + { + _bookStorage.Update(model); + } + else + { + _bookStorage.Insert(model); + } + } + + public void Delete(BookBindingModel model) + { + var element = _bookStorage.GetElement(new BookBindingModel { Id = model.Id }); + if (element == null) + { + throw new Exception("Книга не найдена"); + } + _bookStorage.Delete(model); + } + + public List Read(BookBindingModel model) + { + if (model == null) + { + return _bookStorage.GetFullList(); + } + if (model.Id.HasValue) + { + return new List { _bookStorage.GetElement(model) }; + } + return _bookStorage.GetFilteredList(model); + } + } +} diff --git a/BusinessLogic/BusinessLogic.csproj b/BusinessLogic/BusinessLogic.csproj new file mode 100644 index 0000000..8749333 --- /dev/null +++ b/BusinessLogic/BusinessLogic.csproj @@ -0,0 +1,13 @@ + + + + net6.0 + enable + enable + + + + + + + diff --git a/Contracts/BindingModels/AuthorBindingModel.cs b/Contracts/BindingModels/AuthorBindingModel.cs new file mode 100644 index 0000000..5278183 --- /dev/null +++ b/Contracts/BindingModels/AuthorBindingModel.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.BindingModels +{ + public class AuthorBindingModel + { + public int? Id { get; set; } + public string FIO { get; set; } = string.Empty; + } +} diff --git a/Contracts/BindingModels/BookBindingModel.cs b/Contracts/BindingModels/BookBindingModel.cs new file mode 100644 index 0000000..0c98b02 --- /dev/null +++ b/Contracts/BindingModels/BookBindingModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.BindingModels +{ + public class BookBindingModel + { + public int? Id { get; set; } + public string Name { get; set; } = string.Empty; + public string PicturePath { get; set; } = string.Empty; + public string Author { get; set; } = string.Empty; + public DateTime PublicationDate { get; set; } + + } +} diff --git a/Contracts/BusinessLogicContracts/IAuthorLogic.cs b/Contracts/BusinessLogicContracts/IAuthorLogic.cs new file mode 100644 index 0000000..1c69b5d --- /dev/null +++ b/Contracts/BusinessLogicContracts/IAuthorLogic.cs @@ -0,0 +1,17 @@ +using Contracts.BindingModels; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.BusinessLogicContracts +{ + public interface IAuthorLogic + { + List Read(AuthorBindingModel model); + void CreateOrUpdate(AuthorBindingModel model); + void Delete(AuthorBindingModel model); + } +} diff --git a/Contracts/BusinessLogicContracts/IBookLogic.cs b/Contracts/BusinessLogicContracts/IBookLogic.cs new file mode 100644 index 0000000..ee544a0 --- /dev/null +++ b/Contracts/BusinessLogicContracts/IBookLogic.cs @@ -0,0 +1,17 @@ +using Contracts.BindingModels; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.BusinessLogicContracts +{ + public interface IBookLogic + { + List Read(BookBindingModel model); + void CreateOrUpdate(BookBindingModel model); + void Delete(BookBindingModel model); + } +} diff --git a/Contracts/Contracts.csproj b/Contracts/Contracts.csproj new file mode 100644 index 0000000..132c02c --- /dev/null +++ b/Contracts/Contracts.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/Contracts/StorageContracts/IAuthorStorage.cs b/Contracts/StorageContracts/IAuthorStorage.cs new file mode 100644 index 0000000..85c6398 --- /dev/null +++ b/Contracts/StorageContracts/IAuthorStorage.cs @@ -0,0 +1,21 @@ +using Contracts.BindingModels; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.StorageContracts +{ + public interface IAuthorStorage + { + List GetFullList(); + List GetFilteredList(AuthorBindingModel model); + AuthorViewModel GetElement(AuthorBindingModel model); + + void Insert(AuthorBindingModel model); + void Update(AuthorBindingModel model); + void Delete(AuthorBindingModel model); + } +} diff --git a/Contracts/StorageContracts/IBookStorage.cs b/Contracts/StorageContracts/IBookStorage.cs new file mode 100644 index 0000000..32f7a01 --- /dev/null +++ b/Contracts/StorageContracts/IBookStorage.cs @@ -0,0 +1,21 @@ +using Contracts.BindingModels; +using Contracts.ViewModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.StorageContracts +{ + public interface IBookStorage + { + List GetFullList(); + List GetFilteredList(BookBindingModel model); + BookViewModel GetElement(BookBindingModel model); + + void Insert(BookBindingModel model); + void Update(BookBindingModel model); + void Delete(BookBindingModel model); + } +} diff --git a/Contracts/ViewModels/AuthorViewModel.cs b/Contracts/ViewModels/AuthorViewModel.cs new file mode 100644 index 0000000..98ed903 --- /dev/null +++ b/Contracts/ViewModels/AuthorViewModel.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.ViewModels +{ + public class AuthorViewModel + { + public int? Id { get; set; } + [DisplayName("Имя Автора")] + public string FIO { get; set; } = string.Empty; + } +} diff --git a/Contracts/ViewModels/BookViewModel.cs b/Contracts/ViewModels/BookViewModel.cs new file mode 100644 index 0000000..641cc02 --- /dev/null +++ b/Contracts/ViewModels/BookViewModel.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Contracts.ViewModels +{ + public class BookViewModel { + + public int? Id { get; set; } + [DisplayName("Название")] + public string Name { get; set; } = string.Empty; + [DisplayName("Автор")] + public string Author { get; set; } = string.Empty; + [DisplayName("Дата публикации")] + public DateTime PublicationDate { get; set; } + } +} diff --git a/DatabaseImplement/DatabaseImplement.csproj b/DatabaseImplement/DatabaseImplement.csproj new file mode 100644 index 0000000..b29c04c --- /dev/null +++ b/DatabaseImplement/DatabaseImplement.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + enable + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/DatabaseImplement/Implements/AuthorStorage.cs b/DatabaseImplement/Implements/AuthorStorage.cs new file mode 100644 index 0000000..20a0635 --- /dev/null +++ b/DatabaseImplement/Implements/AuthorStorage.cs @@ -0,0 +1,120 @@ +using Contracts.BindingModels; +using Contracts.StorageContracts; +using Contracts.ViewModels; +using DatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DatabaseImplement.Implements +{ + public class AuthorStorage:IAuthorStorage + { + public void Delete(AuthorBindingModel model) + { + var context = new LibraryDatabase(); + var author = context.Authors.FirstOrDefault(rec => rec.Id == model.Id); + if (author != null) + { + context.Authors.Remove(author); + context.SaveChanges(); + } + else + { + throw new Exception("Автор не найден"); + } + } + + public AuthorViewModel GetElement(AuthorBindingModel model) + { + if (model == null) + { + return null; + } + using var context = new LibraryDatabase(); + + var author = context.Authors + .ToList() + .FirstOrDefault(rec => rec.Id == model.Id || rec.FIO == model.FIO); + return author != null ? CreateModel(author) : null; + } + + + public List GetFilteredList(AuthorBindingModel model) + { + if (model == null) + { + return null; + } + using var context = new LibraryDatabase(); + return context.Authors + .Where(rec => rec.FIO.Contains(model.FIO)) + .Select(CreateModel) + .ToList(); + } + + public List GetFullList() + { + using var context = new LibraryDatabase(); + return context.Authors + .Select(CreateModel) + .ToList(); + } + + public void Insert(AuthorBindingModel model) + { + var context = new LibraryDatabase(); + var transaction = context.Database.BeginTransaction(); + try + { + context.Authors.Add(CreateModel(model, new Author())); + context.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + + public void Update(AuthorBindingModel model) + { + var context = new LibraryDatabase(); + var transaction = context.Database.BeginTransaction(); + try + { + var author = context.Authors.FirstOrDefault(rec => rec.Id == model.Id); + if (author == null) + { + throw new Exception("Автор не найден"); + } + CreateModel(model, author); + context.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + + private static Author CreateModel(AuthorBindingModel model, Author author) + { + author.FIO = model.FIO; + return author; + } + + private static AuthorViewModel CreateModel(Author author) + { + return new AuthorViewModel + { + Id = author.Id, + FIO = author.FIO + }; + } + } +} diff --git a/DatabaseImplement/Implements/BookStorage.cs b/DatabaseImplement/Implements/BookStorage.cs new file mode 100644 index 0000000..725c628 --- /dev/null +++ b/DatabaseImplement/Implements/BookStorage.cs @@ -0,0 +1,124 @@ +using Contracts.BindingModels; +using Contracts.StorageContracts; +using Contracts.ViewModels; +using DatabaseImplement.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DatabaseImplement.Implements +{ + public class BookStorage:IBookStorage + { + public void Delete(BookBindingModel model) + { + var context = new LibraryDatabase(); + var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id); + if (book != null) + { + context.Books.Remove(book); + context.SaveChanges(); + } + else + { + throw new Exception("Книга не найдена"); + } + } + + public BookViewModel GetElement(BookBindingModel model) + { + if (model == null) + { + return null; + } + using var context = new LibraryDatabase(); + var book = context.Books + .ToList() + .FirstOrDefault(rec => rec.Id == model.Id); + return book != null ? CreateModel(book) : null; + } + + public List GetFilteredList(BookBindingModel model) + { + var context = new LibraryDatabase(); + return context.Books + .Where(book => book.Name.Contains(model.Name) && book.Author.Contains(model.Author)) + .ToList() + .Select(CreateModel) + .ToList(); + } + + public List GetFullList() + { + using (var context = new LibraryDatabase()) + { + return context.Books + .ToList() + .Select(CreateModel) + .ToList(); + } + } + + public void Insert(BookBindingModel model) + { + var context = new LibraryDatabase(); + var transaction = context.Database.BeginTransaction(); + try + { + context.Books.Add(CreateModel(model, new Book())); + context.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + + public void Update(BookBindingModel model) + { + var context = new LibraryDatabase(); + var transaction = context.Database.BeginTransaction(); + try + { + var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id); + if (book == null) + { + throw new Exception("Книга не найдена"); + } + CreateModel(model, book); + context.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + + private static Book CreateModel(BookBindingModel model, Book book) + { + book.Name = model.Name; + book.PublicationDate = model.PublicationDate; + book.PicturePath = model.PicturePath; + book.Author = model.Author; + + return book; + } + + private BookViewModel CreateModel(Book book) + { + return new BookViewModel + { + Id = book.Id, + Name = book.Name, + Author = book.Author, + PublicationDate = book.PublicationDate + }; + } + } +} diff --git a/DatabaseImplement/LibraryDatabase.cs b/DatabaseImplement/LibraryDatabase.cs new file mode 100644 index 0000000..6d8201c --- /dev/null +++ b/DatabaseImplement/LibraryDatabase.cs @@ -0,0 +1,28 @@ +using DatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DatabaseImplement +{ + public class LibraryDatabase:DbContext + { + protected override void OnConfiguring(DbContextOptionsBuilder + optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseSqlServer(@"Data Source=DESKTOP-7A1PHA0\SQLEXPRESS; + Initial Catalog=LibraryDatabase; + Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"); + } + base.OnConfiguring(optionsBuilder); + } + public virtual DbSet Books { set; get; } + public virtual DbSet Authors { set; get; } + } +} diff --git a/DatabaseImplement/Migrations/20231116173444_InitialCreate.Designer.cs b/DatabaseImplement/Migrations/20231116173444_InitialCreate.Designer.cs new file mode 100644 index 0000000..00ee1c8 --- /dev/null +++ b/DatabaseImplement/Migrations/20231116173444_InitialCreate.Designer.cs @@ -0,0 +1,75 @@ +// +using System; +using DatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DatabaseImplement.Migrations +{ + [DbContext(typeof(LibraryDatabase))] + [Migration("20231116173444_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DatabaseImplement.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Author") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PicturePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublicationDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DatabaseImplement/Migrations/20231116173444_InitialCreate.cs b/DatabaseImplement/Migrations/20231116173444_InitialCreate.cs new file mode 100644 index 0000000..11b16ad --- /dev/null +++ b/DatabaseImplement/Migrations/20231116173444_InitialCreate.cs @@ -0,0 +1,54 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace DatabaseImplement.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Authors", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FIO = table.Column(type: "nvarchar(max)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Authors", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Books", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(max)", nullable: false), + PicturePath = table.Column(type: "nvarchar(max)", nullable: false), + Author = table.Column(type: "nvarchar(max)", nullable: false), + PublicationDate = table.Column(type: "datetime2", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Books", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Authors"); + + migrationBuilder.DropTable( + name: "Books"); + } + } +} diff --git a/DatabaseImplement/Migrations/LibraryDatabaseModelSnapshot.cs b/DatabaseImplement/Migrations/LibraryDatabaseModelSnapshot.cs new file mode 100644 index 0000000..1da9646 --- /dev/null +++ b/DatabaseImplement/Migrations/LibraryDatabaseModelSnapshot.cs @@ -0,0 +1,72 @@ +// +using System; +using DatabaseImplement; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace DatabaseImplement.Migrations +{ + [DbContext(typeof(LibraryDatabase))] + partial class LibraryDatabaseModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("DatabaseImplement.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FIO") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("DatabaseImplement.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Author") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PicturePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PublicationDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Books"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/DatabaseImplement/Models/Author.cs b/DatabaseImplement/Models/Author.cs new file mode 100644 index 0000000..a198e1e --- /dev/null +++ b/DatabaseImplement/Models/Author.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DatabaseImplement.Models +{ + public class Author + { + public int Id { get; set; } + + [Required] + public string FIO { get; set; } + } +} diff --git a/DatabaseImplement/Models/Book.cs b/DatabaseImplement/Models/Book.cs new file mode 100644 index 0000000..20971d3 --- /dev/null +++ b/DatabaseImplement/Models/Book.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DatabaseImplement.Models +{ + public class Book + { + public int Id { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public string PicturePath { get; set; } + [Required] + public string Author { get; set; } + + [Required] + public DateTime PublicationDate { get; set; } + } +} diff --git a/Library/FormMain.Designer.cs b/Library/FormMain.Designer.cs new file mode 100644 index 0000000..74e1a9f --- /dev/null +++ b/Library/FormMain.Designer.cs @@ -0,0 +1,39 @@ +namespace Library +{ + partial class FormMain + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(800, 450); + this.Text = "Form1"; + } + + #endregion + } +} \ No newline at end of file diff --git a/Library/FormMain.cs b/Library/FormMain.cs new file mode 100644 index 0000000..f00671d --- /dev/null +++ b/Library/FormMain.cs @@ -0,0 +1,10 @@ +namespace Library +{ + public partial class FormMain : Form + { + public FormMain() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/Library/FormMain.resx b/Library/FormMain.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Library/FormMain.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Library/Library.csproj b/Library/Library.csproj new file mode 100644 index 0000000..59e6863 --- /dev/null +++ b/Library/Library.csproj @@ -0,0 +1,29 @@ + + + + WinExe + net6.0-windows + enable + true + enable + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + \ No newline at end of file diff --git a/Library/Program.cs b/Library/Program.cs new file mode 100644 index 0000000..d7ac8b3 --- /dev/null +++ b/Library/Program.cs @@ -0,0 +1,17 @@ +namespace Library +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new FormMain()); + } + } +} \ No newline at end of file diff --git a/TestView/Form1.cs b/TestView/Form1.cs index eca6350..520ce0a 100644 --- a/TestView/Form1.cs +++ b/TestView/Form1.cs @@ -142,10 +142,10 @@ namespace TestView string path = "C:\\Users\\xarla\\OneDrive\\\\test.pdf"; - List<(bool, string)> headers = new List<(bool, string)> { (false, "id"), (false, ""), - (true, ""), (false, ""), - (false, ""), (false, " "), - (false, " ") }; + List<(string, string)> headers = new List<(string, string)> { ("id", "Id"), ("Redaction", ""), + ("", ""), ("AuthorName", ""), + ("AuthorSurname", ""), ("AuthorLife", " "), + ("Title", " ") }; if (pdfTable1.createTable(new DataForPDFTable(path, "test2", heights, merges, headers, books))) MessageBox.Show(""); } diff --git a/TestView/TestView.csproj b/TestView/TestView.csproj index 306de08..06c08c4 100644 --- a/TestView/TestView.csproj +++ b/TestView/TestView.csproj @@ -10,10 +10,15 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/TestView/TestView.sln b/TestView/TestView.sln index 903e4f7..3f641f1 100644 --- a/TestView/TestView.sln +++ b/TestView/TestView.sln @@ -7,6 +7,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestView", "TestView.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ViewComponents", "..\ViewComponents\ViewComponents.csproj", "{45A652EE-B79B-4F5B-BB2A-2A51F5BEA2F1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Contracts", "..\Contracts\Contracts.csproj", "{088EE607-4CC2-4F8D-8571-BA09A4A6A4B5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BusinessLogic", "..\BusinessLogic\BusinessLogic.csproj", "{84504BF2-6F50-435D-B6D4-6A06D48331A0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DatabaseImplement", "..\DatabaseImplement\DatabaseImplement.csproj", "{D9EA1B1E-A8A9-4C13-BFC9-579832B878BF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Library", "..\Library\Library.csproj", "{B74E170A-9AB6-4A1A-9125-42B479DBFBF4}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +29,22 @@ Global {45A652EE-B79B-4F5B-BB2A-2A51F5BEA2F1}.Debug|Any CPU.Build.0 = Debug|Any CPU {45A652EE-B79B-4F5B-BB2A-2A51F5BEA2F1}.Release|Any CPU.ActiveCfg = Release|Any CPU {45A652EE-B79B-4F5B-BB2A-2A51F5BEA2F1}.Release|Any CPU.Build.0 = Release|Any CPU + {088EE607-4CC2-4F8D-8571-BA09A4A6A4B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {088EE607-4CC2-4F8D-8571-BA09A4A6A4B5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {088EE607-4CC2-4F8D-8571-BA09A4A6A4B5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {088EE607-4CC2-4F8D-8571-BA09A4A6A4B5}.Release|Any CPU.Build.0 = Release|Any CPU + {84504BF2-6F50-435D-B6D4-6A06D48331A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84504BF2-6F50-435D-B6D4-6A06D48331A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84504BF2-6F50-435D-B6D4-6A06D48331A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84504BF2-6F50-435D-B6D4-6A06D48331A0}.Release|Any CPU.Build.0 = Release|Any CPU + {D9EA1B1E-A8A9-4C13-BFC9-579832B878BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9EA1B1E-A8A9-4C13-BFC9-579832B878BF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9EA1B1E-A8A9-4C13-BFC9-579832B878BF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9EA1B1E-A8A9-4C13-BFC9-579832B878BF}.Release|Any CPU.Build.0 = Release|Any CPU + {B74E170A-9AB6-4A1A-9125-42B479DBFBF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B74E170A-9AB6-4A1A-9125-42B479DBFBF4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B74E170A-9AB6-4A1A-9125-42B479DBFBF4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B74E170A-9AB6-4A1A-9125-42B479DBFBF4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ViewComponents/NotVisualComponents/DataForPDFTable.cs b/ViewComponents/NotVisualComponents/DataForPDFTable.cs index 124558c..7dfed12 100644 --- a/ViewComponents/NotVisualComponents/DataForPDFTable.cs +++ b/ViewComponents/NotVisualComponents/DataForPDFTable.cs @@ -12,9 +12,9 @@ namespace ViewComponents.NotVisualComponents public string DocumentTitle = string.Empty; //заголовок документа public List Heights; // высота строк public List<(int, int)> Merges; // информаци о объединении ячеек - public List<(bool, string)> Headers; //заголовки шапки таблицы + public List<(string, string)> Headers; //заголовки шапки таблицы public List Data; - public DataForPDFTable(string filePath, string documentTitle, List heights, List<(int, int)> merges, List<(bool, string)> headers, List data) + public DataForPDFTable(string filePath, string documentTitle, List heights, List<(int, int)> merges, List<(string, string)> headers, List data) { FilePath = filePath; DocumentTitle = documentTitle; diff --git a/ViewComponents/NotVisualComponents/PdfTable.cs b/ViewComponents/NotVisualComponents/PdfTable.cs index 89d62a7..6798b6f 100644 --- a/ViewComponents/NotVisualComponents/PdfTable.cs +++ b/ViewComponents/NotVisualComponents/PdfTable.cs @@ -48,7 +48,7 @@ namespace ViewComponents.NotVisualComponents if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга"); } - foreach ((bool, string) el in dataForPDF.Headers) + foreach ((string, string) el in dataForPDF.Headers) if (string.IsNullOrEmpty(el.Item2)) throw new ArgumentException("Элементы шапки не могут быть пустыми"); //создание документа @@ -93,25 +93,8 @@ namespace ViewComponents.NotVisualComponents Row row; for (int i = 0; i < dataForPDF.Headers.Count; i++) { - //если элемент шапки не группируется по строкам - if (dataForPDF.Headers[i].Item1 == false) - { - //стилизация ячейки - row = table.AddRow(); - row.Height = dataForPDF.Heights[i]; - row.Format.Font.Bold = true; - row.Format.Alignment = ParagraphAlignment.Center; - row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2); - row.Cells[0].VerticalAlignment = VerticalAlignment.Center; - row.Cells[0].MergeRight = 1; - - AddTheContent(dataForPDF.Data, table, row.Index, 2); - - mergeIndex++; - } - //если элемент шапки группируются по строкам - if (dataForPDF.Headers[i].Item1 == true) + if (dataForPDF.Merges.Select(x => x.Item1).Contains(mergeIndex)) { mergeRange = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex; mergeIndex = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 + 1; @@ -130,7 +113,7 @@ namespace ViewComponents.NotVisualComponents { i++; row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2); - AddTheContent(dataForPDF.Data, table, row.Index, 2); + AddTheContent(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2); row.Cells[1].VerticalAlignment = VerticalAlignment.Center; row = table.AddRow(); row.Height = dataForPDF.Heights[i]; @@ -140,9 +123,25 @@ namespace ViewComponents.NotVisualComponents i++; row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2); - AddTheContent(dataForPDF.Data, table, row.Index, 2); + AddTheContent(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2); row.Cells[1].VerticalAlignment = VerticalAlignment.Center; - } + } + else //если элемент шапки не группируется по строкам + + { + //стилизация ячейки + row = table.AddRow(); + row.Height = dataForPDF.Heights[i]; + row.Format.Font.Bold = true; + row.Format.Alignment = ParagraphAlignment.Center; + row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2); + row.Cells[0].VerticalAlignment = VerticalAlignment.Center; + row.Cells[0].MergeRight = 1; + + AddTheContent(dataForPDF.Data, table, dataForPDF.Headers[i].Item1, row.Index, 2); + + mergeIndex++; + } } PdfDocumentRenderer renderer = new PdfDocumentRenderer(true); @@ -154,7 +153,7 @@ namespace ViewComponents.NotVisualComponents } //метод заполнения таблицы контентом, заполнение происходит построчно. - public void AddTheContent(List items, Table table, int row_index, int cell_index) + public void AddTheContent(List items, Table table, string header, int row_index, int cell_index) { foreach (Row r in table.Rows) { @@ -166,7 +165,8 @@ namespace ViewComponents.NotVisualComponents T item = items[i]; var type = typeof(T); var fields = type.GetFields(); - r.Cells[cell_index + i].AddParagraph(fields[row_index-1].GetValue(item).ToString()); + var field = fields.FirstOrDefault(x => x.Name.Equals(header)); + r.Cells[cell_index + i].AddParagraph(field.GetValue(item).ToString()); r.Cells[cell_index + i].VerticalAlignment = VerticalAlignment.Center; } } diff --git a/ViewComponents/ViewComponents.csproj b/ViewComponents/ViewComponents.csproj index d699f21..a0c7ace 100644 --- a/ViewComponents/ViewComponents.csproj +++ b/ViewComponents/ViewComponents.csproj @@ -5,6 +5,7 @@ enable true enable + True diff --git a/nuget.config b/nuget.config new file mode 100644 index 0000000..6e95776 --- /dev/null +++ b/nuget.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/nuget.config.bak b/nuget.config.bak new file mode 100644 index 0000000..e69de29