diff --git a/Hospital/Hospital.sln b/Hospital/Hospital.sln index 37d231c..35af821 100644 --- a/Hospital/Hospital.sln +++ b/Hospital/Hospital.sln @@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34525.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HospitalDataModels", "HospitalDataModels\HospitalDataModels.csproj", "{DEC0CC7C-0315-4D11-B383-F5CD19DA7E15}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HospitalDataModels", "HospitalDataModels\HospitalDataModels.csproj", "{DEC0CC7C-0315-4D11-B383-F5CD19DA7E15}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HospitalContracts", "HospitalContracts\HospitalContracts.csproj", "{435124E0-E0A5-4EB8-A46C-C093C47A65F7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HospitalContracts", "HospitalContracts\HospitalContracts.csproj", "{435124E0-E0A5-4EB8-A46C-C093C47A65F7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HospitalDatabaseImplement", "HospitalDatabaseImplement\HospitalDatabaseImplement.csproj", "{595F63B0-79FF-4EBA-9582-2A0652D00B58}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -21,6 +23,10 @@ Global {435124E0-E0A5-4EB8-A46C-C093C47A65F7}.Debug|Any CPU.Build.0 = Debug|Any CPU {435124E0-E0A5-4EB8-A46C-C093C47A65F7}.Release|Any CPU.ActiveCfg = Release|Any CPU {435124E0-E0A5-4EB8-A46C-C093C47A65F7}.Release|Any CPU.Build.0 = Release|Any CPU + {595F63B0-79FF-4EBA-9582-2A0652D00B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {595F63B0-79FF-4EBA-9582-2A0652D00B58}.Debug|Any CPU.Build.0 = Debug|Any CPU + {595F63B0-79FF-4EBA-9582-2A0652D00B58}.Release|Any CPU.ActiveCfg = Release|Any CPU + {595F63B0-79FF-4EBA-9582-2A0652D00B58}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Hospital/HospitalContracts/SearchModels/PatientSearchModel.cs b/Hospital/HospitalContracts/SearchModels/PatientSearchModel.cs index 0cd6bf0..ec49e27 100644 --- a/Hospital/HospitalContracts/SearchModels/PatientSearchModel.cs +++ b/Hospital/HospitalContracts/SearchModels/PatientSearchModel.cs @@ -30,15 +30,5 @@ namespace HospitalContracts.SearchModels /// Идентификатор лечащего врача /// public int? DoctorId { get; set; } - - /// - /// Начало периода выборки данных для отчета - /// - public DateTime? DateFrom { get; set; } - - /// - /// Конец периода выборки данных для отчета - /// - public DateTime? DateTo { get; set; } } } diff --git a/Hospital/HospitalContracts/SearchModels/RecipeSearchModel.cs b/Hospital/HospitalContracts/SearchModels/RecipeSearchModel.cs index b13d68b..34055e5 100644 --- a/Hospital/HospitalContracts/SearchModels/RecipeSearchModel.cs +++ b/Hospital/HospitalContracts/SearchModels/RecipeSearchModel.cs @@ -20,5 +20,15 @@ namespace HospitalContracts.SearchModels /// Идентификатор доктора /// public int? DoctorId { get; set; } + + /// + /// Начало периода выборки данных для отчета + /// + public DateTime? DateFrom { get; set; } + + /// + /// Конец периода выборки данных для отчета + /// + public DateTime? DateTo { get; set; } } } diff --git a/Hospital/HospitalDatabaseImplement/HospitalDatabase.cs b/Hospital/HospitalDatabaseImplement/HospitalDatabase.cs new file mode 100644 index 0000000..92eb7a5 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/HospitalDatabase.cs @@ -0,0 +1,85 @@ +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement +{ + /// + /// Класс для взаимодействия с базой данных + /// + public class HospitalDatabase : DbContext + { + /// + /// Параметры подключения к базе данных + /// + private string _dbConnectionString = @"Data Source=FACTORINO\SQLEXPRESS;Initial Catalog=HospitalDatabase;Integrated Security=True;MultipleActiveResultSets=True;;TrustServerCertificate=True"; + + /// + /// Подключение к базе данных + /// + /// + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (optionsBuilder.IsConfigured == false) + { + optionsBuilder.UseSqlServer(_dbConnectionString); + } + base.OnConfiguring(optionsBuilder); + } + + /// + /// Таблица "Доктора" + /// + public virtual DbSet Doctors { get; set; } + + /// + /// Таблица "Пациенты" + /// + public virtual DbSet Patients { get; set; } + + /// + /// Таблица "Рецепты" + /// + public virtual DbSet Recipes { get; set; } + + /// + /// Таблица "Болезни" + /// + public virtual DbSet Diseases { get; set; } + + /// + /// Таблица "Процедуры" + /// + public virtual DbSet Procedures { get; set; } + + /// + /// Таблица "Лекарства" + /// + public virtual DbSet Medicines { get; set; } + + /// + /// Таблица связи для сущностей "Пациент" и "Рецепт" + /// + public virtual DbSet PatientRecipes { get; set; } + + /// + /// Таблица связи для сущностей "Пациент" и "Процедура" + /// + public virtual DbSet PatientProcedures { get; set; } + + /// + /// Таблица связи для сущностей "Рецепт" и "Лекарство" + /// + public virtual DbSet RecipeMedicines { get; set; } + + /// + /// Таблица связи для сущностей "Процедура" и "Лекарство" + /// + public virtual DbSet ProcedureMedicines { get; set; } + } +} diff --git a/Hospital/HospitalDatabaseImplement/HospitalDatabaseImplement.csproj b/Hospital/HospitalDatabaseImplement/HospitalDatabaseImplement.csproj new file mode 100644 index 0000000..94a8962 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/HospitalDatabaseImplement.csproj @@ -0,0 +1,23 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/Hospital/HospitalDatabaseImplement/Implements/DiseaseStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/DiseaseStorage.cs new file mode 100644 index 0000000..d2adb14 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/DiseaseStorage.cs @@ -0,0 +1,154 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Болезнь" + /// + public class DiseaseStorage : IDiseaseStorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Diseases + .Include(x => x.Recipe) + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(DiseaseSearchModel model) + { + using var context = new HospitalDatabase(); + // Фильтрация по идентификатору рецепта + if (model.RecipeId.HasValue) + { + return context.Diseases + .Include(x => x.Recipe) + .Where(x => x.RecipeId.Equals(model.RecipeId)) + .Select(x => x.GetViewModel) + .ToList(); + } + + // Фильтрация по названию болезни + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Diseases + .Include(x => x.Recipe) + .Where(x => x.Name.Contains(model.Name)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public DiseaseViewModel? GetElement(DiseaseSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Diseases + .Include(x => x.Recipe) + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + // Поиск по названию болезни + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Diseases + .Include(x => x.Recipe) + .FirstOrDefault(x => x.Name.Equals(model.Name)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public DiseaseViewModel? Insert(DiseaseBindingModel model) + { + using var context = new HospitalDatabase(); + var newDisease = Disease.Create(context, model); + if (newDisease == null) + { + return null; + } + + context.Diseases.Add(newDisease); + context.SaveChanges(); + return newDisease.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public DiseaseViewModel? Update(DiseaseBindingModel model) + { + using var context = new HospitalDatabase(); + var disease = context.Diseases + .Include(x => x.Recipe) + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (disease == null) + { + return null; + } + + disease.Update(model); + context.SaveChanges(); + return disease.GetViewModel; + } + + /// + /// Удалить элемент + /// + /// + /// + public DiseaseViewModel? Delete(DiseaseBindingModel model) + { + using var context = new HospitalDatabase(); + var disease = context.Diseases + .Include(x => x.Recipe) + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (disease == null) + { + return null; + } + + context.Diseases.Remove(disease); + context.SaveChanges(); + return disease.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Implements/DoctorStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/DoctorStorage.cs new file mode 100644 index 0000000..69d35b3 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/DoctorStorage.cs @@ -0,0 +1,155 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Доктор" + /// + public class DoctorStorage : IDoctorStorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Doctors + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(DoctorSearchModel model) + { + using var context = new HospitalDatabase(); + // Фильтрация по ФИО + if (!string.IsNullOrEmpty(model.FullName)) + { + return context.Doctors + .Where(x => x.FullName.Contains(model.FullName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + // Фильтрация по логину + if (!string.IsNullOrEmpty(model.Email)) + { + return context.Doctors + .Where(x => x.Email.Contains(model.Email)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public DoctorViewModel? GetElement(DoctorSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Doctors + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + // Поиск по логину и паролю + if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password)) + { + return context.Doctors + .FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password)) + ?.GetViewModel; + } + + // Поиск по логину + if (!string.IsNullOrEmpty(model.Email)) + { + return context.Doctors + .FirstOrDefault(x => x.Email.Equals(model.Email)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public DoctorViewModel? Insert(DoctorBindingModel model) + { + using var context = new HospitalDatabase(); + var newDoctor = Doctor.Create(model); + if (newDoctor == null) + { + return null; + } + + context.Doctors.Add(newDoctor); + context.SaveChanges(); + return newDoctor.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public DoctorViewModel? Update(DoctorBindingModel model) + { + using var context = new HospitalDatabase(); + var doctor = context.Doctors + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (doctor == null) + { + return null; + } + + doctor.Update(model); + context.SaveChanges(); + return doctor.GetViewModel; + } + + /// + /// Удалить элемент + /// + /// + /// + public DoctorViewModel? Delete(DoctorBindingModel model) + { + using var context = new HospitalDatabase(); + var doctor = context.Doctors + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (doctor == null) + { + return null; + } + + context.Doctors.Remove(doctor); + context.SaveChanges(); + return doctor.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Implements/MedicineStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/MedicineStorage.cs new file mode 100644 index 0000000..0e1c46d --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/MedicineStorage.cs @@ -0,0 +1,138 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Лекарство" + /// + public class MedicineStorage : IMedicineStorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Medicines + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(MedicineSearchModel model) + { + using var context = new HospitalDatabase(); + // Фильтрация по названию лекарства + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Medicines + .Where(x => x.Name.Contains(model.Name)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public MedicineViewModel? GetElement(MedicineSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Medicines + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + // Поиск по названию лекарства + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Medicines + .FirstOrDefault(x => x.Name.Equals(model.Name)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public MedicineViewModel? Insert(MedicineBindingModel model) + { + using var context = new HospitalDatabase(); + var newMedicine = Medicine.Create(model); + if (newMedicine == null) + { + return null; + } + + context.Medicines.Add(newMedicine); + context.SaveChanges(); + return newMedicine.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public MedicineViewModel? Update(MedicineBindingModel model) + { + using var context = new HospitalDatabase(); + var medicine = context.Medicines + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (medicine == null) + { + return null; + } + + medicine.Update(model); + context.SaveChanges(); + return medicine.GetViewModel; + } + + /// + /// Удалить элемент + /// + /// + /// + public MedicineViewModel? Delete(MedicineBindingModel model) + { + using var context = new HospitalDatabase(); + var medicine = context.Medicines + .FirstOrDefault(x => x.Equals(model.Id)); + if (medicine == null) + { + return null; + } + + context.Medicines.Remove(medicine); + context.SaveChanges(); + return medicine.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Implements/PatientStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/PatientStorage.cs new file mode 100644 index 0000000..06bdec4 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/PatientStorage.cs @@ -0,0 +1,189 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Пациент" + /// + public class PatientStorage : IPatientStorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude(x => x.Procedure) + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(PatientSearchModel model) + { + using var context = new HospitalDatabase(); + // Фильтрация по идентификатору лечащего врача + if (model.DoctorId.HasValue) + { + return context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude(x => x.Procedure) + .Where(x => x.DoctorId.Equals(model.DoctorId)) + .Select(x => x.GetViewModel) + .ToList(); + } + + // Фильтрация по ФИО + if (!string.IsNullOrEmpty(model.FullName)) + { + return context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude (x => x.Procedure) + .Where(x => x.FullName.Contains(model.FullName)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public PatientViewModel? GetElement(PatientSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude(x => x.Procedure) + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + // Поиск по номеру телефона + if (!string.IsNullOrEmpty(model.Phone)) + { + return context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude(x => x.Procedure) + .FirstOrDefault(x => x.Phone.Equals(model.Phone)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public PatientViewModel? Insert(PatientBindingModel model) + { + using var context = new HospitalDatabase(); + var newPatient = Patient.Create(context, model); + if (newPatient == null) + { + return null; + } + + context.Patients.Add(newPatient); + context.SaveChanges(); + return newPatient.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public PatientViewModel? Update(PatientBindingModel model) + { + using var context = new HospitalDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var patient = context.Patients + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (patient == null) + { + return null; + } + + patient.Update(model); + context.SaveChanges(); + patient.UpdateRecipes(context, model); + patient.UpdateProcedures(context, model); + transaction.Commit(); + return patient.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + /// + /// Удалить элемент + /// + /// + /// + public PatientViewModel? Delete(PatientBindingModel model) + { + using var context = new HospitalDatabase(); + var patient = context.Patients + .Include(x => x.Doctor) + .Include(x => x.Recipes) + .ThenInclude(x => x.Recipe) + .Include(x => x.Procedures) + .ThenInclude(x => x.Procedure) + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (patient == null) + { + return null; + } + + context.Patients.Remove(patient); + context.SaveChanges(); + return patient.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Implements/ProcedureStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/ProcedureStorage.cs new file mode 100644 index 0000000..a7d3206 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/ProcedureStorage.cs @@ -0,0 +1,162 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Процедура" + /// + public class ProcedureStorage : IProcedureStrorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(ProcedureSearchModel model) + { + using var context = new HospitalDatabase(); + // Фильтрация по названию процедуры + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .Where(x => x.Name.Contains(model.Name)) + .Select(x => x.GetViewModel) + .ToList(); + } + + return new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public ProcedureViewModel? GetElement(ProcedureSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + // Поиск по названию процедуры + if (!string.IsNullOrEmpty(model.Name)) + { + return context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Name.Equals(model.Name)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public ProcedureViewModel? Insert(ProcedureBindingModel model) + { + using var context = new HospitalDatabase(); + var newProcedure = Procedure.Create(context, model); + if (newProcedure == null) + { + return null; + } + + context.Procedures.Add(newProcedure); + context.SaveChanges(); + return newProcedure.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public ProcedureViewModel? Update(ProcedureBindingModel model) + { + using var context = new HospitalDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var procedure = context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Id.Equals(model.Id)); + if (procedure == null) + { + return null; + } + + procedure.Update(model); + context.SaveChanges(); + procedure.UpdateMedicines(context, model); + transaction.Commit(); + return procedure.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + /// + /// Удалить элемент + /// + /// + /// + public ProcedureViewModel? Delete(ProcedureBindingModel model) + { + using var context = new HospitalDatabase(); + var procedure = context.Procedures + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Equals(model.Id)); + if (procedure == null) + { + return null; + } + + context.Procedures.Remove(procedure); + context.SaveChanges(); + return procedure.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Implements/RecipeStorage.cs b/Hospital/HospitalDatabaseImplement/Implements/RecipeStorage.cs new file mode 100644 index 0000000..56040e9 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Implements/RecipeStorage.cs @@ -0,0 +1,168 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.SearchModels; +using HospitalContracts.StoragesContracts; +using HospitalContracts.ViewModels; +using HospitalDatabaseImplement.Models; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Implements +{ + /// + /// Хранилище для сущности "Рецепт" + /// + public class RecipeStorage : IRecipeStorage + { + /// + /// Получить полный список + /// + /// + public List GetFullList() + { + using var context = new HospitalDatabase(); + return context.Recipes + .Include(x => x.Doctor) + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .Select(x => x.GetViewModel) + .ToList(); + } + + /// + /// Получить фильтрованный список + /// + /// + /// + public List GetFilteredList(RecipeSearchModel model) + { + using var context = new HospitalDatabase(); + // Получения всех записей для фильтрации по одному или нескольким параметрам + var recipes = context.Recipes + .Include(x => x.Doctor) + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .Select(x => x.GetViewModel) + .ToList(); + + // Фильтрация по идентификатору доктора + if (model.DoctorId.HasValue) + { + recipes = recipes + .Where(x => x.DoctorId.Equals(model.DoctorId)) + .ToList(); + } + + // Фильтрация по датам + if (model.DateFrom.HasValue && model.DateTo.HasValue) + { + recipes = recipes + .Where(x => x.IssueDate >= model.DateFrom && x.IssueDate <= model.DateTo) + .ToList(); + } + + return recipes ?? new(); + } + + /// + /// Получить элемент списка + /// + /// + /// + public RecipeViewModel? GetElement(RecipeSearchModel model) + { + using var context = new HospitalDatabase(); + // Поиск по идентификатору + if (model.Id.HasValue) + { + return context.Recipes + .Include(x => x.Doctor) + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Id.Equals(model.Id)) + ?.GetViewModel; + } + + return null; + } + + /// + /// Добавить элемент + /// + /// + /// + public RecipeViewModel? Insert(RecipeBindingModel model) + { + using var context = new HospitalDatabase(); + var newRecipe = Recipe.Create(context, model); + if (newRecipe == null) + { + return null; + } + + context.Recipes.Add(newRecipe); + context.SaveChanges(); + return newRecipe.GetViewModel; + } + + /// + /// Редактировать элемент + /// + /// + /// + public RecipeViewModel? Update(RecipeBindingModel model) + { + using var context = new HospitalDatabase(); + using var transaction = context.Database.BeginTransaction(); + try + { + var recipe = context.Recipes + .Include(x => x.Doctor) + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(rec => rec.Id == model.Id); + if (recipe == null) + { + return null; + } + + recipe.Update(model); + context.SaveChanges(); + recipe.UpdateMedicines(context, model); + transaction.Commit(); + return recipe.GetViewModel; + } + catch + { + transaction.Rollback(); + throw; + } + } + + /// + /// Удалить элемент + /// + /// + /// + public RecipeViewModel? Delete(RecipeBindingModel model) + { + using var context = new HospitalDatabase(); + var recipe = context.Recipes + .Include(x => x.Doctor) + .Include(x => x.Medicines) + .ThenInclude(x => x.Medicine) + .FirstOrDefault(x => x.Equals(model.Id)); + if (recipe == null) + { + return null; + } + + context.Recipes.Remove(recipe); + context.SaveChanges(); + return recipe.GetViewModel; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Disease.cs b/Hospital/HospitalDatabaseImplement/Models/Disease.cs new file mode 100644 index 0000000..7ca3093 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Disease.cs @@ -0,0 +1,98 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Болезнь" + /// + public class Disease : IDiseaseModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// Название болезни + /// + [Required] + [MaxLength(30)] + public string Name { get; private set; } = string.Empty; + + /// + /// Симптомы заболевания + /// + [MaxLength(100)] + public string? Symptoms { get; private set; } + + /// + /// Идентификатор рецепта + /// + [ForeignKey("RecipeId")] + public int RecipeId { get; private set; } + + /// + /// Сущность "Рецепт" + /// + public virtual Recipe Recipe { get; private set; } = new(); + + /// + /// Создать сущность + /// + /// + /// + /// + public static Disease? Create(HospitalDatabase context, DiseaseBindingModel model) + { + if (model == null) + { + return null; + } + + return new Disease() + { + Id = model.Id, + Name = model.Name, + Symptoms = model.Symptoms, + RecipeId = model.RecipeId, + Recipe = context.Recipes + .First(x => x.Id == model.RecipeId) + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(DiseaseBindingModel model) + { + if (model == null) + { + return; + } + + Name = model.Name; + Symptoms = model.Symptoms; + } + + /// + /// Получить модель представления + /// + public DiseaseViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + Symptoms = Symptoms, + RecipeId = RecipeId + }; + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Doctor.cs b/Hospital/HospitalDatabaseImplement/Models/Doctor.cs new file mode 100644 index 0000000..c4a1e54 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Doctor.cs @@ -0,0 +1,102 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Enums; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Доктор" + /// + public class Doctor : IDoctorModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// ФИО доктора + /// + [Required] + [MaxLength(100)] + public string FullName { get; private set; } = string.Empty; + + /// + /// Должность доктора + /// + [Required] + public DoctorPost Post { get; private set; } + + /// + /// Логин (электронная почта) + /// + [Required] + [MaxLength(30)] + public string Email { get; private set; } = string.Empty; + + /// + /// Пароль + /// + [Required] + [MaxLength(30)] + public string Password { get; private set; } = string.Empty; + + /// + /// Создать сущность + /// + /// + /// + public static Doctor? Create(DoctorBindingModel model) + { + if (model == null) + { + return null; + } + + return new Doctor() + { + Id = model.Id, + FullName = model.FullName, + Post = model.Post, + Email = model.Email, + Password = model.Password + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(DoctorBindingModel model) + { + if (model == null) + { + return; + } + + FullName = model.FullName; + Post = model.Post; + Email = model.Email; + Password = model.Password; + } + + /// + /// Получить модель представления + /// + public DoctorViewModel GetViewModel => new() + { + Id = Id, + FullName = FullName, + Post = Post, + Email = Email, + Password = Password + }; + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Medicine.cs b/Hospital/HospitalDatabaseImplement/Models/Medicine.cs new file mode 100644 index 0000000..3602a6c --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Medicine.cs @@ -0,0 +1,81 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Лекарство" + /// + public class Medicine : IMedicineModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// Название лекарства + /// + [Required] + [MaxLength(30)] + public string Name { get; private set; } = string.Empty; + + /// + /// Описание лекарства + /// + [MaxLength(100)] + public string? Description { get; private set; } + + /// + /// Создать сущность + /// + /// + /// + public static Medicine? Create(MedicineBindingModel model) + { + if (model == null) + { + return null; + } + + return new Medicine() + { + Id = model.Id, + Name = model.Name, + Description = model.Description + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(MedicineBindingModel model) + { + if (model == null) + { + return; + } + + Name = model.Name; + Description = model.Description; + } + + /// + /// Получить модель представления + /// + public MedicineViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + Description = Description + }; + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Patient.cs b/Hospital/HospitalDatabaseImplement/Models/Patient.cs new file mode 100644 index 0000000..e1c8fb7 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Patient.cs @@ -0,0 +1,231 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Пациент" + /// + public class Patient : IPatientModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// ФИО пациента + /// + [Required] + [MaxLength(100)] + public string FullName { get; private set; } = string.Empty; + + /// + /// Дата рождения пациента + /// + [Required] + public DateTime BirthDate { get; private set; } + + /// + /// Номер телефона пациента + /// + [Required] + [MaxLength(16)] + public string Phone { get; private set; } = string.Empty; + + /// + /// Идентификатор лечащего врача + /// + [ForeignKey("DoctorId")] + public int DoctorId { get; private set; } + + /// + /// Лечащий врач + /// + public virtual Doctor Doctor { get; private set; } = new(); + + /// + /// Связь с таблицей связи для сущностей "Пациент" и "Рецепт" + /// + [ForeignKey("PatientId")] + public virtual List Recipes { get; set; } = new(); + + /// + /// Список рецептов пациента + /// + private Dictionary? _patientRecipes = null; + + /// + /// Список рецептов пациента + /// + [NotMapped] + public Dictionary PatientRecipes + { + get + { + if (_patientRecipes == null) + { + _patientRecipes = Recipes + .ToDictionary(recPR => recPR.RecipeId, recPR => (recPR.Recipe as IRecipeModel)); + } + return _patientRecipes; + } + } + + /// + /// Связь с таблицей связи для сущностей "Пациент" и "Процедура" + /// + [ForeignKey("PatientId")] + public virtual List Procedures { get; set; } = new(); + + /// + /// Список процедур пациента + /// + private Dictionary? _patientProcedures = null; + + /// + /// Список процедур пациента + /// + [NotMapped] + public Dictionary PatientProcedures + { + get + { + if (_patientProcedures == null) + { + _patientProcedures = Procedures + .ToDictionary(recPP => recPP.ProcedureId, recPP => (recPP.Procedure as IProcedureModel)); + } + return _patientProcedures; + } + } + + /// + /// Cоздать сущность + /// + /// + /// + /// + public static Patient? Create(HospitalDatabase context, PatientBindingModel model) + { + if (model == null) + { + return null; + } + + return new Patient() + { + Id = model.Id, + FullName = model.FullName, + BirthDate = model.BirthDate, + Phone = model.Phone, + DoctorId = model.DoctorId, + Doctor = context.Doctors + .First(x => x.Id == model.DoctorId), + Recipes = model.PatientRecipes.Select(x => new PatientRecipe + { + Recipe = context.Recipes.First(y => y.Id == x.Key) + }).ToList(), + Procedures = model.PatientProcedures.Select(x => new PatientProcedure + { + Procedure = context.Procedures.First(y => y.Id == x.Key) + }).ToList() + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(PatientBindingModel model) + { + if (model == null) + { + return; + } + + FullName = model.FullName; + BirthDate = model.BirthDate; + Phone = model.Phone; + } + + /// + /// Получить модель представления + /// + public PatientViewModel GetViewModel => new() + { + Id = Id, + FullName = FullName, + BirthDate = BirthDate, + Phone = Phone, + DoctorId = DoctorId, + DoctorFullName = Doctor.FullName, + PatientRecipes = PatientRecipes, + PatientProcedures = PatientProcedures + }; + + /// + /// Обновить связи с рецептами + /// + /// + /// + public void UpdateRecipes(HospitalDatabase context, PatientBindingModel model) + { + var patientRecipes = context.PatientRecipes.Where(rec => rec.PatientId == model.Id).ToList(); + if (patientRecipes != null && patientRecipes.Count > 0) + { + // Удаление рецептов, не относящихся к пациенту + context.PatientRecipes.RemoveRange(patientRecipes.Where(rec => !model.PatientRecipes.ContainsKey(rec.RecipeId))); + context.SaveChanges(); + } + + var patient = context.Patients.First(x => x.Id == Id); + foreach (var pr in model.PatientRecipes) + { + context.PatientRecipes.Add(new PatientRecipe + { + Patient = patient, + Recipe = context.Recipes.First(x => x.Id == pr.Key) + }); + context.SaveChanges(); + } + _patientRecipes = null; + } + + /// + /// Обновить связи с процедурами + /// + /// + /// + public void UpdateProcedures(HospitalDatabase context, PatientBindingModel model) + { + var patientProcedures = context.PatientProcedures.Where(rec => rec.PatientId == model.Id).ToList(); + if (patientProcedures != null && patientProcedures.Count > 0) + { + // Удаление процедур, не относящихся к пациенту + context.PatientProcedures.RemoveRange(patientProcedures.Where(rec => !model.PatientProcedures.ContainsKey(rec.ProcedureId))); + context.SaveChanges(); + } + + var patient = context.Patients.First(x => x.Id == Id); + foreach (var pp in model.PatientProcedures) + { + context.PatientProcedures.Add(new PatientProcedure + { + Patient = patient, + Procedure = context.Procedures.First(x => x.Id == pp.Key) + }); + context.SaveChanges(); + } + _patientProcedures = null; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/PatientProcedure.cs b/Hospital/HospitalDatabaseImplement/Models/PatientProcedure.cs new file mode 100644 index 0000000..f3968e1 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/PatientProcedure.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Класс связи для сущностей "Пациент" и "Процедура" + /// + public class PatientProcedure + { + /// + /// Идентификатор + /// + public int Id { get; set; } + + /// + /// Идентификатор пациента + /// + [Required] + public int PatientId { get; set; } + + /// + /// Сущность "Пациент" + /// + public virtual Patient Patient { get; set; } = new(); + + /// + /// Идентификатор процедуры + /// + [Required] + public int ProcedureId { get; set; } + + /// + /// Сущность "Процедура" + /// + public virtual Procedure Procedure { get; set; } = new(); + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/PatientRecipe.cs b/Hospital/HospitalDatabaseImplement/Models/PatientRecipe.cs new file mode 100644 index 0000000..8208f79 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/PatientRecipe.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Класс связи для сущностей "Пациент" и "Рецепт" + /// + public class PatientRecipe + { + /// + /// Идентификатор + /// + public int Id { get; set; } + + /// + /// Идентификатор пациента + /// + [Required] + public int PatientId { get; set; } + + /// + /// Сущность "Пациент" + /// + public virtual Patient Patient { get; set; } = new(); + + /// + /// Идентификатор рецепта + /// + [Required] + public int RecipeId { get; set; } + + /// + /// Сущность "Рецепт" + /// + public virtual Recipe Recipe { get; set; } = new(); + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Procedure.cs b/Hospital/HospitalDatabaseImplement/Models/Procedure.cs new file mode 100644 index 0000000..e937b98 --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Procedure.cs @@ -0,0 +1,144 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Процедура" + /// + public class Procedure : IProcedureModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// Название процедуры + /// + [Required] + [MaxLength(30)] + public string Name { get; private set; } = string.Empty; + + /// + /// Описание процедуры + /// + [MaxLength(100)] + public string? Description { get; private set; } + + /// + /// Связь с таблицей связи для сущностей "Процедура" и "Лекарство" + /// + [ForeignKey("ProcedureId")] + public virtual List Medicines { get; set; } = new(); + + /// + /// Список лекарств для процедуры + /// + private Dictionary? _procedureMedicines = null; + + /// + /// Список лекарств для процедуры + /// + [NotMapped] + public Dictionary ProcedureMedicines + { + get + { + if (_procedureMedicines == null) + { + _procedureMedicines = Medicines + .ToDictionary(recPM => recPM.MedicineId, recPM => (recPM.Medicine as IMedicineModel)); + } + return _procedureMedicines; + } + } + + /// + /// Создать сущность + /// + /// + /// + /// + public static Procedure? Create(HospitalDatabase context, ProcedureBindingModel model) + { + if (model == null) + { + return null; + } + + return new Procedure() + { + Id = model.Id, + Name = model.Name, + Description = model.Description, + Medicines = model.ProcedureMedicines.Select(x => new ProcedureMedicine + { + Medicine = context.Medicines.First(y => y.Id == x.Key) + }).ToList() + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(ProcedureBindingModel model) + { + if (model == null) + { + return; + } + + Name = model.Name; + Description = model.Description; + } + + /// + /// Получить модель представления + /// + public ProcedureViewModel GetViewModel => new() + { + Id = Id, + Name = Name, + Description = Description, + ProcedureMedicines = ProcedureMedicines + }; + + /// + /// Обновить связи с лекарствами + /// + /// + /// + public void UpdateMedicines(HospitalDatabase context, ProcedureBindingModel model) + { + var procedureMedicines = context.ProcedureMedicines.Where(rec => rec.ProcedureId == model.Id).ToList(); + if (procedureMedicines != null && procedureMedicines.Count > 0) + { + // Удаление лекарств, не относящихся к процедуре + context.ProcedureMedicines.RemoveRange(procedureMedicines.Where(rec => !model.ProcedureMedicines.ContainsKey(rec.MedicineId))); + context.SaveChanges(); + } + + var procedure = context.Procedures.First(x => x.Id == Id); + foreach (var pm in model.ProcedureMedicines) + { + context.ProcedureMedicines.Add(new ProcedureMedicine + { + Procedure = procedure, + Medicine = context.Medicines.First(x => x.Id == pm.Key) + }); + context.SaveChanges(); + } + _procedureMedicines = null; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/ProcedureMedicine.cs b/Hospital/HospitalDatabaseImplement/Models/ProcedureMedicine.cs new file mode 100644 index 0000000..0fc396d --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/ProcedureMedicine.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Класс связи для сущностей "Процедура" и "Лекарство" + /// + public class ProcedureMedicine + { + /// + /// Идентификатор + /// + public int Id { get; set; } + + /// + /// Идентификатор процедуры + /// + [Required] + public int ProcedureId { get; set; } + + /// + /// Сущность "Процедура" + /// + public virtual Procedure Procedure { get; set; } = new(); + + /// + /// Идентификатор лекарства + /// + [Required] + public int MedicineId { get; set; } + + /// + /// Сущность "Лекарство" + /// + public virtual Medicine Medicine { get; set; } = new(); + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/Recipe.cs b/Hospital/HospitalDatabaseImplement/Models/Recipe.cs new file mode 100644 index 0000000..db69c0c --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/Recipe.cs @@ -0,0 +1,150 @@ +using HospitalContracts.BindingModels; +using HospitalContracts.ViewModels; +using HospitalDataModels.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Сущность "Рецепт" + /// + public class Recipe : IRecipeModel + { + /// + /// Идентификатор + /// + public int Id { get; private set; } + + /// + /// Дата выписки рецепта + /// + [Required] + public DateTime IssueDate { get; private set; } = DateTime.Now; + + /// + /// Идентификатор доктора + /// + [ForeignKey("DoctorId")] + public int DoctorId { get; private set; } + + /// + /// Сущность "Доктор" + /// + public virtual Doctor Doctor { get; private set; } = new(); + + /// + /// Связь с таблицей связи для сущностей "Рецепт" и "Лекарство" + /// + [ForeignKey("RecipeId")] + public virtual List Medicines { get; set; } = new(); + + /// + /// Список лекарств в рецепте + /// + private Dictionary? _recipeMedicines = null; + + /// + /// Список лекарств в рецепте + /// + [NotMapped] + public Dictionary RecipeMedicines + { + get + { + if (_recipeMedicines == null) + { + _recipeMedicines = Medicines + .ToDictionary(recRM => recRM.MedicineId, recRM => (recRM.Medicine as IMedicineModel)); + } + return _recipeMedicines; + } + } + + /// + /// Cоздать сущность + /// + /// + /// + /// + public static Recipe? Create(HospitalDatabase context, RecipeBindingModel model) + { + if (model == null) + { + return null; + } + + return new Recipe() + { + Id = model.Id, + IssueDate = model.IssueDate, + DoctorId = model.DoctorId, + Doctor = context.Doctors + .First(x => x.Id == model.DoctorId), + Medicines = model.RecipeMedicines.Select(x => new RecipeMedicine + { + Medicine = context.Medicines.First(y => y.Id == x.Key) + }).ToList() + }; + } + + /// + /// Изменить сущность + /// + /// + public void Update(RecipeBindingModel model) + { + if (model == null) + { + return; + } + + IssueDate = model.IssueDate; + } + + /// + /// Получить модель представления + /// + public RecipeViewModel GetViewModel => new() + { + Id = Id, + IssueDate = IssueDate, + DoctorId = DoctorId, + DoctorFullName = Doctor.FullName, + RecipeMedicines = RecipeMedicines + }; + + /// + /// Обновить связи с лекарствами + /// + /// + /// + public void UpdateMedicines(HospitalDatabase context, RecipeBindingModel model) + { + var recipeMedicines = context.RecipeMedicines.Where(rec => rec.RecipeId == model.Id).ToList(); + if (recipeMedicines != null && recipeMedicines.Count > 0) + { + // Удаление лекарств, не относящихся к рецепту + context.RecipeMedicines.RemoveRange(recipeMedicines.Where(rec => !model.RecipeMedicines.ContainsKey(rec.MedicineId))); + context.SaveChanges(); + } + + var recipe = context.Recipes.First(x => x.Id == Id); + foreach (var rm in model.RecipeMedicines) + { + context.RecipeMedicines.Add(new RecipeMedicine + { + Recipe = recipe, + Medicine = context.Medicines.First(x => x.Id == rm.Key) + }); + context.SaveChanges(); + } + _recipeMedicines = null; + } + } +} diff --git a/Hospital/HospitalDatabaseImplement/Models/RecipeMedicine.cs b/Hospital/HospitalDatabaseImplement/Models/RecipeMedicine.cs new file mode 100644 index 0000000..95994bb --- /dev/null +++ b/Hospital/HospitalDatabaseImplement/Models/RecipeMedicine.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HospitalDatabaseImplement.Models +{ + /// + /// Класс связи для сущностей "Рецепт" и "Лекарство" + /// + public class RecipeMedicine + { + /// + /// Идентификатор + /// + public int Id { get; set; } + + /// + /// Идентификатор рецепта + /// + [Required] + public int RecipeId { get; set; } + + /// + /// Сущность "Рецепт" + /// + public virtual Recipe Recipe { get; set; } = new(); + + /// + /// Идентификатор лекарства + /// + [Required] + public int MedicineId { get; set; } + + /// + /// Сущность "Лекарство" + /// + public virtual Medicine Medicine { get; set; } = new(); + } +} diff --git a/Записка/ER-diagram.png b/Записка/ER-diagram.png deleted file mode 100644 index 4948bb3..0000000 Binary files a/Записка/ER-diagram.png and /dev/null differ diff --git a/Записка/ERD-diagram.png b/Записка/ERD-diagram.png new file mode 100644 index 0000000..a746bb0 Binary files /dev/null and b/Записка/ERD-diagram.png differ diff --git a/Записка/Пример отчета Word.docx b/Записка/Пример отчета Word.docx new file mode 100644 index 0000000..501e64a Binary files /dev/null and b/Записка/Пример отчета Word.docx differ