diff --git a/BookBusinessLogic/BookBusinessLogic.csproj b/BookBusinessLogic/BookBusinessLogic.csproj
new file mode 100644
index 0000000..9461248
--- /dev/null
+++ b/BookBusinessLogic/BookBusinessLogic.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/BookBusinessLogic/BusinessLogic/BookLogic.cs b/BookBusinessLogic/BusinessLogic/BookLogic.cs
new file mode 100644
index 0000000..c1bd92e
--- /dev/null
+++ b/BookBusinessLogic/BusinessLogic/BookLogic.cs
@@ -0,0 +1,61 @@
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookBusinessLogic.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 { Title = model.Title });
+ 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 { Title = model.Title });
+ 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.GetFullList();
+ }
+ }
+}
diff --git a/BookBusinessLogic/BusinessLogic/HistoryLogic.cs b/BookBusinessLogic/BusinessLogic/HistoryLogic.cs
new file mode 100644
index 0000000..2074059
--- /dev/null
+++ b/BookBusinessLogic/BusinessLogic/HistoryLogic.cs
@@ -0,0 +1,66 @@
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookBusinessLogic.BusinessLogic
+{
+ public class HistoryLogic : IHistoryLogic
+ {
+ private readonly IHistoryStorage _historyStorage;
+
+ public HistoryLogic(IHistoryStorage historyStorage)
+ {
+ _historyStorage = historyStorage;
+ }
+
+ public List Read(HistoryBindingModel model)
+ {
+ if(model == null)
+ {
+ return _historyStorage.GetFullList();
+ }
+ if (model.Id.HasValue) {
+ return new List
+ {
+ _historyStorage.GetElement(model)
+ };
+ }
+ return _historyStorage.GetHistoryByBookId(model.BookId);
+ }
+
+ public void CreateOrUpdate(HistoryBindingModel model)
+ {
+ var element = _historyStorage.GetElement(
+ new HistoryBindingModel
+ {
+ Id = model.Id,
+ });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new Exception("Такая связь уже существует");
+ }
+ _historyStorage.Insert(model);
+ }
+
+ public void Delete(HistoryBindingModel model)
+ {
+ var element = _historyStorage.GetElement(new HistoryBindingModel
+ {
+ Id = model.Id
+ });
+
+ if (element == null)
+ {
+ throw new Exception("Навык не найден");
+ }
+
+ _historyStorage.Delete(model);
+ }
+ }
+}
diff --git a/BookBusinessLogic/BusinessLogic/ReaderLogic.cs b/BookBusinessLogic/BusinessLogic/ReaderLogic.cs
new file mode 100644
index 0000000..a680ac5
--- /dev/null
+++ b/BookBusinessLogic/BusinessLogic/ReaderLogic.cs
@@ -0,0 +1,62 @@
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookBusinessLogic.BusinessLogic
+{
+ public class ReaderLogic : IReaderLogic
+ {
+ private readonly IReaderStorage _readerStorage;
+
+ public ReaderLogic(IReaderStorage readerStorage)
+ {
+ _readerStorage = readerStorage;
+ }
+
+ public void CreateOrUpdate(ReaderBindingModel model)
+ {
+ var element = _readerStorage.GetElement(new ReaderBindingModel { Name = model.Name });
+ if (element != null && element.Id != model.Id)
+ {
+ throw new Exception("Книги с таким названием тут нет");
+ }
+ if (model.Id.HasValue)
+ {
+ _readerStorage.Update(model);
+ }
+ else
+ {
+ _readerStorage.Insert(model);
+ }
+ }
+
+ public void Delete(ReaderBindingModel model)
+ {
+ var element = _readerStorage.GetElement(new ReaderBindingModel { Name = model.Name });
+ if (element == null)
+ {
+ throw new Exception("Книги с таким названием тут нет");
+ }
+ _readerStorage.Delete(model);
+ }
+
+ public List Read(ReaderBindingModel model)
+ {
+ if (model == null)
+ return _readerStorage.GetFullList();
+ if (model.Id.HasValue)
+ {
+ return new List {
+ _readerStorage.GetElement(model)
+ };
+ }
+ return _readerStorage.GetFullList();
+ }
+ }
+}
diff --git a/BookContract/BindingModels/BookBindingModel.cs b/BookContract/BindingModels/BookBindingModel.cs
new file mode 100644
index 0000000..b339bad
--- /dev/null
+++ b/BookContract/BindingModels/BookBindingModel.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BindingModels
+{
+ public class BookBindingModel
+ {
+ public int? Id { get; set; }
+ public string Title { get; set; } = string.Empty;
+ public string BookType { get; set; } = string.Empty;
+ public string Annotation { get; set; } = string.Empty;
+ public List ReaderIds { get; set; } = new List();
+ }
+}
diff --git a/BookContract/BindingModels/HistoryBindingModel.cs b/BookContract/BindingModels/HistoryBindingModel.cs
new file mode 100644
index 0000000..9848add
--- /dev/null
+++ b/BookContract/BindingModels/HistoryBindingModel.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BindingModels
+{
+ public class HistoryBindingModel
+ {
+ public int? Id { get; set; }
+ public int BookId { get; set; }
+ public int ReaderId { get; set; }
+ public DateTime DateBorrowed { get; set; }
+ }
+}
diff --git a/BookContract/BindingModels/ReaderBindingModel.cs b/BookContract/BindingModels/ReaderBindingModel.cs
new file mode 100644
index 0000000..b0b515c
--- /dev/null
+++ b/BookContract/BindingModels/ReaderBindingModel.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BindingModels
+{
+ public class ReaderBindingModel
+ {
+ public int? Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+ }
+}
diff --git a/BookContract/BookContract.csproj b/BookContract/BookContract.csproj
new file mode 100644
index 0000000..9e6160a
--- /dev/null
+++ b/BookContract/BookContract.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
diff --git a/BookContract/BusinessLogicContracts/IBookLogic.cs b/BookContract/BusinessLogicContracts/IBookLogic.cs
new file mode 100644
index 0000000..42609b2
--- /dev/null
+++ b/BookContract/BusinessLogicContracts/IBookLogic.cs
@@ -0,0 +1,19 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BusinessLogicContracts
+{
+ public interface IBookLogic
+ {
+ List Read(BookBindingModel model);
+
+ void CreateOrUpdate(BookBindingModel model);
+
+ void Delete(BookBindingModel model);
+ }
+}
diff --git a/BookContract/BusinessLogicContracts/IHistoryLogic.cs b/BookContract/BusinessLogicContracts/IHistoryLogic.cs
new file mode 100644
index 0000000..8cd98c6
--- /dev/null
+++ b/BookContract/BusinessLogicContracts/IHistoryLogic.cs
@@ -0,0 +1,19 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BusinessLogicContracts
+{
+ public interface IHistoryLogic
+ {
+ List Read(HistoryBindingModel model);
+
+ void CreateOrUpdate(HistoryBindingModel model);
+
+ void Delete(HistoryBindingModel model);
+ }
+}
diff --git a/BookContract/BusinessLogicContracts/IReaderLogic.cs b/BookContract/BusinessLogicContracts/IReaderLogic.cs
new file mode 100644
index 0000000..a51ec90
--- /dev/null
+++ b/BookContract/BusinessLogicContracts/IReaderLogic.cs
@@ -0,0 +1,19 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.BusinessLogicContracts
+{
+ public interface IReaderLogic
+ {
+ List Read(ReaderBindingModel model);
+
+ void CreateOrUpdate(ReaderBindingModel model);
+
+ void Delete(ReaderBindingModel model);
+ }
+}
diff --git a/BookContract/StorageContracts/IBookStorage.cs b/BookContract/StorageContracts/IBookStorage.cs
new file mode 100644
index 0000000..e5f747d
--- /dev/null
+++ b/BookContract/StorageContracts/IBookStorage.cs
@@ -0,0 +1,20 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.StorageContracts
+{
+ public interface IBookStorage
+ {
+ List GetFullList();
+ List GetFilterList(BookBindingModel model);
+ BookViewModel GetElement(BookBindingModel model);
+ void Insert(BookBindingModel model);
+ void Update(BookBindingModel model);
+ void Delete(BookBindingModel model);
+ }
+}
diff --git a/BookContract/StorageContracts/IHistoryStorage.cs b/BookContract/StorageContracts/IHistoryStorage.cs
new file mode 100644
index 0000000..d85c432
--- /dev/null
+++ b/BookContract/StorageContracts/IHistoryStorage.cs
@@ -0,0 +1,19 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.StorageContracts
+{
+ public interface IHistoryStorage
+ {
+ HistoryViewModel GetElement(HistoryBindingModel model);
+ List GetFullList();
+ List GetHistoryByBookId(int bookId);
+ void Insert(HistoryBindingModel model);
+ void Delete(HistoryBindingModel model);
+ }
+}
diff --git a/BookContract/StorageContracts/IReaderStorage.cs b/BookContract/StorageContracts/IReaderStorage.cs
new file mode 100644
index 0000000..56f9755
--- /dev/null
+++ b/BookContract/StorageContracts/IReaderStorage.cs
@@ -0,0 +1,20 @@
+using BookContract.BindingModels;
+using BookContract.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.StorageContracts
+{
+ public interface IReaderStorage
+ {
+ List GetFullList();
+ List GetFilterList(ReaderBindingModel model);
+ ReaderViewModel GetElement(ReaderBindingModel model);
+ void Insert(ReaderBindingModel model);
+ void Update(ReaderBindingModel model);
+ void Delete(ReaderBindingModel model);
+ }
+}
diff --git a/BookContract/ViewModels/BookViewModel.cs b/BookContract/ViewModels/BookViewModel.cs
new file mode 100644
index 0000000..282792a
--- /dev/null
+++ b/BookContract/ViewModels/BookViewModel.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.ViewModels
+{
+ public class BookViewModel
+ {
+ public int Id { get; set; }
+ public string Title { get; set; } = string.Empty;
+ public string BookType { get; set; } = string.Empty;
+ public string Annotation { get; set; } = string.Empty;
+ public List LastReaders { get; set; } = new List();
+ }
+}
diff --git a/BookContract/ViewModels/HistoryViewModel.cs b/BookContract/ViewModels/HistoryViewModel.cs
new file mode 100644
index 0000000..17b454c
--- /dev/null
+++ b/BookContract/ViewModels/HistoryViewModel.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.ViewModels
+{
+ public class HistoryViewModel
+ {
+ public int Id { get; set; }
+ public int BookId { get; set; }
+ public int ReaderId { get; set; }
+ public DateTime DateBorrowed { get; set; }
+ }
+}
diff --git a/BookContract/ViewModels/ReaderViewModel.cs b/BookContract/ViewModels/ReaderViewModel.cs
new file mode 100644
index 0000000..b6ef1e5
--- /dev/null
+++ b/BookContract/ViewModels/ReaderViewModel.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookContract.ViewModels
+{
+ public class ReaderViewModel
+ {
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+ }
+}
diff --git a/BookDatabaseImplement/BookDatabaseImplement.csproj b/BookDatabaseImplement/BookDatabaseImplement.csproj
new file mode 100644
index 0000000..c7ac457
--- /dev/null
+++ b/BookDatabaseImplement/BookDatabaseImplement.csproj
@@ -0,0 +1,27 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
diff --git a/BookDatabaseImplement/BookLibraryDatabase .cs b/BookDatabaseImplement/BookLibraryDatabase .cs
new file mode 100644
index 0000000..09acd05
--- /dev/null
+++ b/BookDatabaseImplement/BookLibraryDatabase .cs
@@ -0,0 +1,28 @@
+using BookDatabaseImplement.Model;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement
+{
+ public class BookLibraryDatabase : DbContext
+ {
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ if (optionsBuilder.IsConfigured == false)
+ {
+ optionsBuilder.UseNpgsql(@"Host=localhost;Port=5432;Database=BookLibrary_db;Username=postgres;Password=password");
+ }
+ base.OnConfiguring(optionsBuilder);
+ AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
+ AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);
+ }
+ public virtual DbSet Books { get; set; }
+ public virtual DbSet Readers { get; set; }
+ public virtual DbSet Histories { get; set; }
+ }
+}
diff --git a/BookDatabaseImplement/Implements/BookStorage.cs b/BookDatabaseImplement/Implements/BookStorage.cs
new file mode 100644
index 0000000..01c13cf
--- /dev/null
+++ b/BookDatabaseImplement/Implements/BookStorage.cs
@@ -0,0 +1,126 @@
+using BookContract.BindingModels;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using BookDatabaseImplement.Model;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Implements
+{
+ public class BookStorage : IBookStorage
+ {
+ private Book CreateModel(BookBindingModel model, Book book)
+ {
+ book.Title = model.Title;
+ book.BookType = model.BookType;
+ book.Annotation = model.Annotation;
+
+ return book;
+ }
+
+ private BookViewModel CreateModel(Book book)
+ {
+ return new BookViewModel
+ {
+ Id = book.Id,
+ Title = book.Title,
+ BookType = book.BookType,
+ Annotation = book.Annotation,
+ LastReaders = book.LastReaders
+ .OrderByDescending(h => h.DateBorrowed)
+ .Select(h => new ReaderViewModel
+ {
+ Id = h.Reader.Id,
+ Name = h.Reader.Name
+ })
+ .Take(6)
+ .ToList()
+ };
+ }
+
+ public List GetFullList()
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Books
+ .Include(b => b.LastReaders)
+ .ThenInclude(h => h.Reader)
+ .ToList()
+ .Select(CreateModel)
+ .ToList();
+ }
+
+ public List GetFilterList(BookBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Books
+ .Where(book => book.BookType.Contains(model.BookType))
+ .ToList().Select(CreateModel).ToList();
+ }
+
+ public BookViewModel? GetElement(BookBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id || rec.Title == model.Title);
+ return book != null ? CreateModel(book) : null;
+ }
+
+ public void Insert(BookBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ using 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)
+ {
+ using var context = new BookLibraryDatabase();
+ using 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;
+ }
+ }
+
+ public void Delete(BookBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var book = context.Books.FirstOrDefault(rec => rec.Id == model.Id);
+
+ if (book != null)
+ {
+ context.Books.Remove(book);
+ context.SaveChanges();
+ }
+ else
+ {
+ throw new Exception("Книга не найдена");
+ }
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Implements/HistoryStorage.cs b/BookDatabaseImplement/Implements/HistoryStorage.cs
new file mode 100644
index 0000000..64a02e4
--- /dev/null
+++ b/BookDatabaseImplement/Implements/HistoryStorage.cs
@@ -0,0 +1,87 @@
+using BookContract.BindingModels;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using BookDatabaseImplement.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Implements
+{
+ public class HistoryStorage : IHistoryStorage
+ {
+ private History CreateModel(HistoryBindingModel model, History history)
+ {
+ history.BookId = model.BookId;
+ history.ReaderId = model.ReaderId;
+ history.DateBorrowed = model.DateBorrowed;
+ return history;
+ }
+
+ private HistoryViewModel CreateModel(History history)
+ {
+ return new HistoryViewModel
+ {
+ Id = history.Id,
+ BookId = history.BookId,
+ ReaderId = history.ReaderId,
+ DateBorrowed = history.DateBorrowed
+ };
+ }
+
+ public List GetFullList()
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Histories.ToList().Select(CreateModel).ToList();
+ }
+
+ public List GetHistoryByBookId(int bookId)
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Histories
+ .Where(history => history.BookId == bookId)
+ .ToList().Select(CreateModel).ToList();
+ }
+
+ public HistoryViewModel? GetElement(HistoryBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var history = context.Histories.FirstOrDefault(rec => rec.Id == model.Id);
+ return history != null ? CreateModel(history) : null;
+ }
+
+ public void Insert(HistoryBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ using var transaction = context.Database.BeginTransaction();
+ try
+ {
+ context.Histories.Add(CreateModel(model, new History()));
+ context.SaveChanges();
+ transaction.Commit();
+ }
+ catch
+ {
+ transaction.Rollback();
+ throw;
+ }
+ }
+
+ public void Delete(HistoryBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var history = context.Histories.FirstOrDefault(rec => rec.Id == model.Id);
+ if (history != null)
+ {
+ context.Histories.Remove(history);
+ context.SaveChanges();
+ }
+ else
+ {
+ throw new Exception("Запись истории не найдена");
+ }
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Implements/ReaderStorage.cs b/BookDatabaseImplement/Implements/ReaderStorage.cs
new file mode 100644
index 0000000..63771a8
--- /dev/null
+++ b/BookDatabaseImplement/Implements/ReaderStorage.cs
@@ -0,0 +1,105 @@
+using BookContract.BindingModels;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using BookDatabaseImplement.Model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Implements
+{
+ public class ReaderStorage : IReaderStorage
+ {
+ private Reader CreateModel(ReaderBindingModel model, Reader reader)
+ {
+ reader.Name = model.Name;
+ return reader;
+ }
+
+ private ReaderViewModel CreateModel(Reader reader)
+ {
+ return new ReaderViewModel
+ {
+ Id = reader.Id,
+ Name = reader.Name
+ };
+ }
+
+ public List GetFullList()
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Readers.ToList().Select(CreateModel).ToList();
+ }
+
+ public List GetFilterList(ReaderBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ return context.Readers
+ .Where(reader => reader.Name.Contains(model.Name))
+ .ToList().Select(CreateModel).ToList();
+ }
+
+ public ReaderViewModel? GetElement(ReaderBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var reader = context.Readers.FirstOrDefault(rec => rec.Id == model.Id || rec.Name == model.Name);
+ return reader != null ? CreateModel(reader) : null;
+ }
+
+ public void Insert(ReaderBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ using var transaction = context.Database.BeginTransaction();
+ try
+ {
+ context.Readers.Add(CreateModel(model, new Reader()));
+ context.SaveChanges();
+ transaction.Commit();
+ }
+ catch
+ {
+ transaction.Rollback();
+ throw;
+ }
+ }
+
+ public void Update(ReaderBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ using var transaction = context.Database.BeginTransaction();
+ try
+ {
+ var reader = context.Readers.FirstOrDefault(rec => rec.Id == model.Id);
+ if (reader == null)
+ {
+ throw new Exception("Читатель не найден");
+ }
+ CreateModel(model, reader);
+ context.SaveChanges();
+ transaction.Commit();
+ }
+ catch
+ {
+ transaction.Rollback();
+ throw;
+ }
+ }
+
+ public void Delete(ReaderBindingModel model)
+ {
+ using var context = new BookLibraryDatabase();
+ var reader = context.Readers.FirstOrDefault(rec => rec.Id == model.Id);
+ if (reader != null)
+ {
+ context.Readers.Remove(reader);
+ context.SaveChanges();
+ }
+ else
+ {
+ throw new Exception("Читатель не найден");
+ }
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Migrations/20241028084936_InitMig.Designer.cs b/BookDatabaseImplement/Migrations/20241028084936_InitMig.Designer.cs
new file mode 100644
index 0000000..d31d884
--- /dev/null
+++ b/BookDatabaseImplement/Migrations/20241028084936_InitMig.Designer.cs
@@ -0,0 +1,128 @@
+//
+using System;
+using BookDatabaseImplement;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BookDatabaseImplement.Migrations
+{
+ [DbContext(typeof(BookLibraryDatabase))]
+ [Migration("20241028084936_InitMig")]
+ partial class InitMig
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Book", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Annotation")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("BookType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Books");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.History", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BookId")
+ .HasColumnType("integer");
+
+ b.Property("DateBorrowed")
+ .HasColumnType("timestamp without time zone");
+
+ b.Property("ReaderId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BookId");
+
+ b.HasIndex("ReaderId");
+
+ b.ToTable("Histories");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Reader", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Readers");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.History", b =>
+ {
+ b.HasOne("BookDatabaseImplement.Model.Book", "Book")
+ .WithMany("LastReaders")
+ .HasForeignKey("BookId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BookDatabaseImplement.Model.Reader", "Reader")
+ .WithMany("BorrowedBooks")
+ .HasForeignKey("ReaderId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Book");
+
+ b.Navigation("Reader");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Book", b =>
+ {
+ b.Navigation("LastReaders");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Reader", b =>
+ {
+ b.Navigation("BorrowedBooks");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Migrations/20241028084936_InitMig.cs b/BookDatabaseImplement/Migrations/20241028084936_InitMig.cs
new file mode 100644
index 0000000..6279d46
--- /dev/null
+++ b/BookDatabaseImplement/Migrations/20241028084936_InitMig.cs
@@ -0,0 +1,94 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BookDatabaseImplement.Migrations
+{
+ ///
+ public partial class InitMig : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Books",
+ columns: table => new
+ {
+ Id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ Title = table.Column(type: "text", nullable: false),
+ BookType = table.Column(type: "text", nullable: false),
+ Annotation = table.Column(type: "character varying(200)", maxLength: 200, nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Books", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Readers",
+ columns: table => new
+ {
+ Id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ Name = table.Column(type: "text", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Readers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Histories",
+ columns: table => new
+ {
+ Id = table.Column(type: "integer", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ BookId = table.Column(type: "integer", nullable: false),
+ ReaderId = table.Column(type: "integer", nullable: false),
+ DateBorrowed = table.Column(type: "timestamp without time zone", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Histories", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Histories_Books_BookId",
+ column: x => x.BookId,
+ principalTable: "Books",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Histories_Readers_ReaderId",
+ column: x => x.ReaderId,
+ principalTable: "Readers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Histories_BookId",
+ table: "Histories",
+ column: "BookId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Histories_ReaderId",
+ table: "Histories",
+ column: "ReaderId");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Histories");
+
+ migrationBuilder.DropTable(
+ name: "Books");
+
+ migrationBuilder.DropTable(
+ name: "Readers");
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Migrations/BookLibraryDatabaseModelSnapshot.cs b/BookDatabaseImplement/Migrations/BookLibraryDatabaseModelSnapshot.cs
new file mode 100644
index 0000000..8132ac0
--- /dev/null
+++ b/BookDatabaseImplement/Migrations/BookLibraryDatabaseModelSnapshot.cs
@@ -0,0 +1,125 @@
+//
+using System;
+using BookDatabaseImplement;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace BookDatabaseImplement.Migrations
+{
+ [DbContext(typeof(BookLibraryDatabase))]
+ partial class BookLibraryDatabaseModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.10")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Book", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Annotation")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("BookType")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Books");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.History", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BookId")
+ .HasColumnType("integer");
+
+ b.Property("DateBorrowed")
+ .HasColumnType("timestamp without time zone");
+
+ b.Property("ReaderId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BookId");
+
+ b.HasIndex("ReaderId");
+
+ b.ToTable("Histories");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Reader", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Readers");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.History", b =>
+ {
+ b.HasOne("BookDatabaseImplement.Model.Book", "Book")
+ .WithMany("LastReaders")
+ .HasForeignKey("BookId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BookDatabaseImplement.Model.Reader", "Reader")
+ .WithMany("BorrowedBooks")
+ .HasForeignKey("ReaderId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Book");
+
+ b.Navigation("Reader");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Book", b =>
+ {
+ b.Navigation("LastReaders");
+ });
+
+ modelBuilder.Entity("BookDatabaseImplement.Model.Reader", b =>
+ {
+ b.Navigation("BorrowedBooks");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BookDatabaseImplement/Model/Book.cs b/BookDatabaseImplement/Model/Book.cs
new file mode 100644
index 0000000..daadbfc
--- /dev/null
+++ b/BookDatabaseImplement/Model/Book.cs
@@ -0,0 +1,28 @@
+ using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Model
+{
+ public class Book
+ {
+ public int Id { get; set; }
+
+ [Required]
+ public string Title { get; set; } = string.Empty;
+
+ [Required]
+ public string BookType { get; set; } = string.Empty;
+
+ [Required]
+ [StringLength(200, MinimumLength = 100)]
+ public string Annotation { get; set; } = string.Empty;
+
+ [InverseProperty("Book")]
+ public List LastReaders { get; set; } = new List();
+ }
+}
diff --git a/BookDatabaseImplement/Model/History.cs b/BookDatabaseImplement/Model/History.cs
new file mode 100644
index 0000000..b24ac13
--- /dev/null
+++ b/BookDatabaseImplement/Model/History.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Model
+{
+ public class History
+ {
+ public int Id { get; set; }
+
+ [Required]
+ public int BookId { get; set; }
+
+ [ForeignKey("BookId")]
+ public Book Book { get; set; }
+
+ [Required]
+ public int ReaderId { get; set; }
+
+ [ForeignKey("ReaderId")]
+ public Reader Reader { get; set; }
+
+ [Required]
+ public DateTime DateBorrowed { get; set; }
+ }
+}
diff --git a/BookDatabaseImplement/Model/Reader.cs b/BookDatabaseImplement/Model/Reader.cs
new file mode 100644
index 0000000..2810a12
--- /dev/null
+++ b/BookDatabaseImplement/Model/Reader.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BookDatabaseImplement.Model
+{
+ public class Reader
+ {
+ public int Id { get; set; }
+
+ [Required]
+ public string Name { get; set; } = string.Empty;
+
+ public List BorrowedBooks { get; set; } = new List();
+ }
+}
diff --git a/COP3.sln b/COP3.sln
new file mode 100644
index 0000000..1a54cfc
--- /dev/null
+++ b/COP3.sln
@@ -0,0 +1,49 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.11.35303.130
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookContract", "BookContract\BookContract.csproj", "{B6BADCB3-6326-4D78-B7EA-33E648B98B45}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BookDatabaseImplement", "BookDatabaseImplement\BookDatabaseImplement.csproj", "{1ADFC6AE-FBB7-405C-9D0E-80E1EB5E15F9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Desktop", "Desktop\Desktop.csproj", "{193A14AF-1D66-4FE6-B463-A985BE2E63BB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{67A97857-028F-4E5B-A9CF-BDEFD8699C25}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookBusinessLogic", "BookBusinessLogic\BookBusinessLogic.csproj", "{1FCCA8B4-9391-4F9E-AF1F-556C56EAA352}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B6BADCB3-6326-4D78-B7EA-33E648B98B45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6BADCB3-6326-4D78-B7EA-33E648B98B45}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6BADCB3-6326-4D78-B7EA-33E648B98B45}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6BADCB3-6326-4D78-B7EA-33E648B98B45}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1ADFC6AE-FBB7-405C-9D0E-80E1EB5E15F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1ADFC6AE-FBB7-405C-9D0E-80E1EB5E15F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1ADFC6AE-FBB7-405C-9D0E-80E1EB5E15F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1ADFC6AE-FBB7-405C-9D0E-80E1EB5E15F9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {193A14AF-1D66-4FE6-B463-A985BE2E63BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {193A14AF-1D66-4FE6-B463-A985BE2E63BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {193A14AF-1D66-4FE6-B463-A985BE2E63BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {193A14AF-1D66-4FE6-B463-A985BE2E63BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {67A97857-028F-4E5B-A9CF-BDEFD8699C25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {67A97857-028F-4E5B-A9CF-BDEFD8699C25}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {67A97857-028F-4E5B-A9CF-BDEFD8699C25}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {67A97857-028F-4E5B-A9CF-BDEFD8699C25}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FCCA8B4-9391-4F9E-AF1F-556C56EAA352}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FCCA8B4-9391-4F9E-AF1F-556C56EAA352}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FCCA8B4-9391-4F9E-AF1F-556C56EAA352}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FCCA8B4-9391-4F9E-AF1F-556C56EAA352}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {05DA2BD9-9B6D-4B78-897A-1EEAEEA4139A}
+ EndGlobalSection
+EndGlobal
diff --git a/COP3/COP3.csproj b/COP3/COP3.csproj
new file mode 100644
index 0000000..6252fad
--- /dev/null
+++ b/COP3/COP3.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
diff --git a/COP3/Class1.cs b/COP3/Class1.cs
new file mode 100644
index 0000000..9e2f64c
--- /dev/null
+++ b/COP3/Class1.cs
@@ -0,0 +1,7 @@
+namespace COP3
+{
+ public class Class1
+ {
+
+ }
+}
diff --git a/Desktop/Desktop.csproj b/Desktop/Desktop.csproj
new file mode 100644
index 0000000..eb78b53
--- /dev/null
+++ b/Desktop/Desktop.csproj
@@ -0,0 +1,27 @@
+
+
+
+ WinExe
+ net8.0-windows
+ enable
+ true
+ enable
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Desktop/Form1.Designer.cs b/Desktop/Form1.Designer.cs
new file mode 100644
index 0000000..4107780
--- /dev/null
+++ b/Desktop/Form1.Designer.cs
@@ -0,0 +1,58 @@
+namespace Desktop
+{
+ partial class Form1
+ {
+ ///
+ /// 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()
+ {
+ bookList = new Components.VisualComponents.UserListBox();
+ SuspendLayout();
+ //
+ // bookList
+ //
+ bookList.Location = new Point(-1, 1);
+ bookList.Name = "bookList";
+ bookList.SelectedIndex = -1;
+ bookList.Size = new Size(803, 450);
+ bookList.TabIndex = 0;
+ //
+ // Form1
+ //
+ AutoScaleDimensions = new SizeF(7F, 15F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(800, 450);
+ Controls.Add(bookList);
+ Name = "Form1";
+ Text = "Form1";
+ Load += Form1_Load;
+ ResumeLayout(false);
+ }
+
+ #endregion
+
+ private Components.VisualComponents.UserListBox bookList;
+ }
+}
diff --git a/Desktop/Form1.cs b/Desktop/Form1.cs
new file mode 100644
index 0000000..ee92cad
--- /dev/null
+++ b/Desktop/Form1.cs
@@ -0,0 +1,45 @@
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookDatabaseImplement.Implements;
+
+namespace Desktop
+{
+ public partial class Form1 : Form
+ {
+ private IBookLogic _bookLogicl;
+ private IHistoryLogic _historyLogicl;
+ private IReaderLogic _readerLogicl;
+
+
+ public Form1(IBookLogic bookLogic, IHistoryLogic historyLogicl, IReaderLogic readerLogicl)
+ {
+ InitializeComponent();
+ _bookLogicl = bookLogic;
+ _historyLogicl = historyLogicl;
+ _readerLogicl = readerLogicl;
+
+ bookList.SetTemplate("{", "}", " {BookType} {Id} {Title} {Annotation} ");
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ var books = _bookLogicl.Read(null);
+
+ foreach (var book in books)
+ {
+ bookList.Add(new BookBindingModel { Id = book.Id, Title = book.Title, BookType = book.BookType, Annotation = book.Annotation });
+ }
+ }
+
+ private void controlTextBox1_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private void bookList_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ }
+}
diff --git a/Desktop/Form1.resx b/Desktop/Form1.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/Desktop/Form1.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/Desktop/Program.cs b/Desktop/Program.cs
new file mode 100644
index 0000000..5cb4534
--- /dev/null
+++ b/Desktop/Program.cs
@@ -0,0 +1,51 @@
+using BookBusinessLogic.BusinessLogic;
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookContract.StorageContracts;
+using BookDatabaseImplement.Implements;
+using Unity;
+using Unity.Lifetime;
+
+namespace Desktop
+{
+ internal static class Program
+ {
+ private static IUnityContainer container = null;
+
+ public static IUnityContainer Container
+ {
+ get
+ {
+ if (container == null)
+ {
+ container = BuildUnityContainer();
+ }
+ return container;
+ }
+ }
+
+ [STAThread]
+ static void Main()
+ {
+ Application.SetHighDpiMode(HighDpiMode.SystemAware);
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(Container.Resolve());
+ }
+
+ private static IUnityContainer BuildUnityContainer()
+ {
+ var currentContainer = new UnityContainer();
+
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+ currentContainer.RegisterType(new HierarchicalLifetimeManager());
+
+ return currentContainer;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Test/Program.cs b/Test/Program.cs
new file mode 100644
index 0000000..573b981
--- /dev/null
+++ b/Test/Program.cs
@@ -0,0 +1,119 @@
+using BookBusinessLogic.BusinessLogic;
+using BookContract.BindingModels;
+using BookContract.BusinessLogicContracts;
+using BookContract.StorageContracts;
+using BookContract.ViewModels;
+using BookDatabaseImplement.Implements;
+using Microsoft.Extensions.DependencyInjection;
+
+//var bookStorage = new BookStorage();
+//var readerStorage = new ReaderStorage();
+//var historyStorage = new HistoryStorage();
+
+//// создание книг
+//var book1 = new bookbindingmodel { title = "книга 1", booktype = "фантастика", annotation = "аннотация к книге 1" };
+//var book2 = new bookbindingmodel { title = "книга 2", booktype = "приключения", annotation = "аннотация к книге 2" };
+
+//bookstorage.insert(book1);
+//bookstorage.insert(book2);
+
+//console.writeline("книги созданы.");
+
+//// создание читателей
+//var reader1 = new readerbindingmodel { name = "читатель 1" };
+//var reader2 = new readerbindingmodel { name = "читатель 2" };
+//var reader3 = new readerbindingmodel { name = "читатель 3" };
+
+//readerstorage.insert(reader1);
+//readerstorage.insert(reader2);
+//readerstorage.insert(reader3);
+
+//console.writeline("читатели созданы.");
+
+
+//historystorage.insert(new historybindingmodel { bookid = 2, readerid = 1, dateborrowed = datetime.now });
+//historystorage.insert(new historybindingmodel { bookid = 2, readerid = 2, dateborrowed = datetime.now });
+//historystorage.insert(new historybindingmodel { bookid = 2, readerid = 3, dateborrowed = datetime.now });
+
+
+//Console.WriteLine("Читатели добавлены к книге.");
+
+//var books = bookStorage.GetFullList();
+//foreach (var book in books)
+//{
+// Console.WriteLine($"Title: {book.Title}");
+// Console.WriteLine("Readers: ");
+// foreach (var reader in book.LastReaders)
+// {
+// Console.WriteLine($"- {reader.Name} (ID: {reader.Id})");
+// }
+//}
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ //Настройка DI (если используете)
+ var serviceProvider = new ServiceCollection()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .BuildServiceProvider();
+
+ var bookLogic = serviceProvider.GetService();
+ var readerLogic = serviceProvider.GetService();
+ var historyLogic = serviceProvider.GetService();
+
+ var book1 = new BookBindingModel();
+ book1.Id = 1;
+ book1.BookType = "HHHH";
+ book1.Annotation = "asdafaf";
+ book1.Title = "Title";
+ //bookLogic.CreateOrUpdate(book1);
+
+ /* var pay1 = new HistoryBindingModel();
+ pay1.DateBorrowed = DateTime.Now;
+ pay1.Id = 5;
+ pay1.BookId = 1;
+ pay1.ReaderId = 4;
+
+ historyLogic.CreateOrUpdate(pay1);
+
+ DisplayAllBooks(bookLogic);
+
+ var readers = readerLogic.Read(null);
+ foreach (var reader in readers)
+ {
+ Console.WriteLine($"ID: {reader.Id}, Name: {reader.Name}");
+ }*/
+ }
+
+ private static void DisplayAllBooks(IBookLogic bookLogic)
+ {
+ /*try
+ {
+ var books = bookLogic.Read(null);
+ if (books.Count == 0)
+ {
+ Console.WriteLine("Нет доступных книг.");
+ return;
+ }
+
+ foreach (var book in books)
+ {
+ Console.WriteLine($"ID: {book.Id}, Title: {book.Title}, Type: {book.BookType}, Annotation: {book.Annotation}");
+ foreach (var reader in book.LastReaders)
+ {
+ Console.WriteLine($"- {reader.Name}");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Ошибка: {ex.Message}");
+ }*/
+ }
+}
\ No newline at end of file
diff --git a/Test/Test.csproj b/Test/Test.csproj
new file mode 100644
index 0000000..23d6da0
--- /dev/null
+++ b/Test/Test.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+