Лаб2 сдано. Лаб3 - бд готова

This commit is contained in:
Артем Харламов 2023-11-29 20:58:13 +04:00
parent dfca5ba119
commit 65e207cf3d
34 changed files with 1120 additions and 30 deletions

View File

@ -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<AuthorViewModel> Read(AuthorBindingModel model)
{
if (model == null)
{
return _authorStorage.GetFullList();
}
if (model.Id.HasValue)
{
return new List<AuthorViewModel> { _authorStorage.GetElement(model) };
}
return _authorStorage.GetFilteredList(model);
}
}
}

View File

@ -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<BookViewModel> Read(BookBindingModel model)
{
if (model == null)
{
return _bookStorage.GetFullList();
}
if (model.Id.HasValue)
{
return new List<BookViewModel> { _bookStorage.GetElement(model) };
}
return _bookStorage.GetFilteredList(model);
}
}
}

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup>
</Project>

View File

@ -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;
}
}

View File

@ -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; }
}
}

View File

@ -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<AuthorViewModel> Read(AuthorBindingModel model);
void CreateOrUpdate(AuthorBindingModel model);
void Delete(AuthorBindingModel model);
}
}

View File

@ -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<BookViewModel> Read(BookBindingModel model);
void CreateOrUpdate(BookBindingModel model);
void Delete(BookBindingModel model);
}
}

View File

@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -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<AuthorViewModel> GetFullList();
List<AuthorViewModel> GetFilteredList(AuthorBindingModel model);
AuthorViewModel GetElement(AuthorBindingModel model);
void Insert(AuthorBindingModel model);
void Update(AuthorBindingModel model);
void Delete(AuthorBindingModel model);
}
}

View File

@ -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<BookViewModel> GetFullList();
List<BookViewModel> GetFilteredList(BookBindingModel model);
BookViewModel GetElement(BookBindingModel model);
void Insert(BookBindingModel model);
void Update(BookBindingModel model);
void Delete(BookBindingModel model);
}
}

View File

@ -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;
}
}

View File

@ -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; }
}
}

View File

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contracts\Contracts.csproj" />
</ItemGroup>
</Project>

View File

@ -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<AuthorViewModel> 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<AuthorViewModel> 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
};
}
}
}

View File

@ -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<BookViewModel> 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<BookViewModel> 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
};
}
}
}

View File

@ -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<Book> Books { set; get; }
public virtual DbSet<Author> Authors { set; get; }
}
}

View File

@ -0,0 +1,75 @@
// <auto-generated />
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
{
/// <inheritdoc />
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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Authors");
});
modelBuilder.Entity("DatabaseImplement.Models.Book", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Author")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PicturePath")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("PublicationDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Books");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace DatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitialCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Authors",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
FIO = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Authors", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Books",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Name = table.Column<string>(type: "nvarchar(max)", nullable: false),
PicturePath = table.Column<string>(type: "nvarchar(max)", nullable: false),
Author = table.Column<string>(type: "nvarchar(max)", nullable: false),
PublicationDate = table.Column<DateTime>(type: "datetime2", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Books", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Authors");
migrationBuilder.DropTable(
name: "Books");
}
}
}

View File

@ -0,0 +1,72 @@
// <auto-generated />
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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("FIO")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Authors");
});
modelBuilder.Entity("DatabaseImplement.Models.Book", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Author")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("PicturePath")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("PublicationDate")
.HasColumnType("datetime2");
b.HasKey("Id");
b.ToTable("Books");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

39
Library/FormMain.Designer.cs generated Normal file
View File

@ -0,0 +1,39 @@
namespace Library
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
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
}
}

10
Library/FormMain.cs Normal file
View File

@ -0,0 +1,10 @@
namespace Library
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
}
}

120
Library/FormMain.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

29
Library/Library.csproj Normal file
View File

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CustomComponents" Version="1.0.0" />
<PackageReference Include="KOP_Labs" Version="1.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PDFsharp-MigraDoc" Version="1.50.5147" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="ViewComponents" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BusinessLogic\BusinessLogic.csproj" />
<ProjectReference Include="..\Contracts\Contracts.csproj" />
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
</ItemGroup>
</Project>

17
Library/Program.cs Normal file
View File

@ -0,0 +1,17 @@
namespace Library
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[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());
}
}
}

View File

@ -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<BookInfo>(path, "test2", heights, merges, headers, books))) MessageBox.Show("Óñïåõ");
}

View File

@ -10,10 +10,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DatabaseImplement\DatabaseImplement.csproj" />
<ProjectReference Include="..\ViewComponents\ViewComponents.csproj" />
</ItemGroup>

View File

@ -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

View File

@ -12,9 +12,9 @@ namespace ViewComponents.NotVisualComponents
public string DocumentTitle = string.Empty; //заголовок документа
public List<int> Heights; // высота строк
public List<(int, int)> Merges; // информаци о объединении ячеек
public List<(bool, string)> Headers; //заголовки шапки таблицы
public List<(string, string)> Headers; //заголовки шапки таблицы
public List<T> Data;
public DataForPDFTable(string filePath, string documentTitle, List<int> heights, List<(int, int)> merges, List<(bool, string)> headers, List<T> data)
public DataForPDFTable(string filePath, string documentTitle, List<int> heights, List<(int, int)> merges, List<(string, string)> headers, List<T> data)
{
FilePath = filePath;
DocumentTitle = documentTitle;

View File

@ -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<T>(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<T>(dataForPDF.Data, table, row.Index, 2);
AddTheContent<T>(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<T>(dataForPDF.Data, table, row.Index, 2);
AddTheContent<T>(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<T>(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<T>(List<T> items, Table table, int row_index, int cell_index)
public void AddTheContent<T>(List<T> 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;
}
}

View File

@ -5,6 +5,7 @@
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>

10
nuget.config Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="ComponentsForKOP" value="C:\ComponentsForKOP" />
</packageSources>
<activePackageSource>
<!-- this tells that all of them are active -->
<add key="All" value="(Aggregate source)" />
</activePackageSource>
</configuration>

0
nuget.config.bak Normal file
View File