Compare commits

...

7 Commits

76 changed files with 5678 additions and 0 deletions

View File

@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.6.33815.320
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudentEnrollmentView", "StudentEnrollmentView\StudentEnrollmentView.csproj", "{9F2D2847-BC2D-43E8-95D3-65FF657A4BC9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudentEnrollmentDatabaseImplement", "StudentEnrollmentDatabaseImplement\StudentEnrollmentDatabaseImplement.csproj", "{0E15CFEE-D946-455E-9E4E-90FA14674F7D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudentEnrollmentDataModels", "StudentEnrollmentDataModels\StudentEnrollmentDataModels.csproj", "{1E2E27BF-4895-4191-9669-A5822D7FA989}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudentEnrollmentBusinessLogic", "StudentEnrollmentBusinessLogic\StudentEnrollmentBusinessLogic.csproj", "{A53CE753-75B2-44CC-9BE8-AE478C1A5796}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudentEnrollmentContracts", "StudentEnrollmentContracts\StudentEnrollmentContracts.csproj", "{2F21A9AA-6FA9-4113-88C0-9C7BCCFBB822}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9F2D2847-BC2D-43E8-95D3-65FF657A4BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9F2D2847-BC2D-43E8-95D3-65FF657A4BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9F2D2847-BC2D-43E8-95D3-65FF657A4BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9F2D2847-BC2D-43E8-95D3-65FF657A4BC9}.Release|Any CPU.Build.0 = Release|Any CPU
{0E15CFEE-D946-455E-9E4E-90FA14674F7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0E15CFEE-D946-455E-9E4E-90FA14674F7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0E15CFEE-D946-455E-9E4E-90FA14674F7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0E15CFEE-D946-455E-9E4E-90FA14674F7D}.Release|Any CPU.Build.0 = Release|Any CPU
{1E2E27BF-4895-4191-9669-A5822D7FA989}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1E2E27BF-4895-4191-9669-A5822D7FA989}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1E2E27BF-4895-4191-9669-A5822D7FA989}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1E2E27BF-4895-4191-9669-A5822D7FA989}.Release|Any CPU.Build.0 = Release|Any CPU
{A53CE753-75B2-44CC-9BE8-AE478C1A5796}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A53CE753-75B2-44CC-9BE8-AE478C1A5796}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A53CE753-75B2-44CC-9BE8-AE478C1A5796}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A53CE753-75B2-44CC-9BE8-AE478C1A5796}.Release|Any CPU.Build.0 = Release|Any CPU
{2F21A9AA-6FA9-4113-88C0-9C7BCCFBB822}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F21A9AA-6FA9-4113-88C0-9C7BCCFBB822}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F21A9AA-6FA9-4113-88C0-9C7BCCFBB822}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F21A9AA-6FA9-4113-88C0-9C7BCCFBB822}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6F203950-511C-4D26-A9CF-129D159AE690}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,106 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentBusinessLogic
{
public class CourseLogic : ICourseLogic
{
private readonly ILogger _logger;
private readonly ICourseStorage _courseStorage;
public CourseLogic(ILogger<CourseLogic> logger, ICourseStorage
courseStorage)
{
_logger = logger;
_courseStorage = courseStorage;
}
public List<CourseViewModel>? ReadList(CourseSearchModel? model)
{
_logger.LogInformation("ReadList. CourseName:{CourseName}.Id:{ Id}", model?.name, model?.course_id);
var list = model == null ? _courseStorage.GetFullList() :
_courseStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public CourseViewModel? ReadElement(CourseSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. CourseName:{CourseName}.Id:{ Id}", model.name, model.course_id);
var element = _courseStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.course_id);
return element;
}
public bool Create(CourseBindingModel model)
{
CheckModel(model);
if (_courseStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(CourseBindingModel model)
{
CheckModel(model);
if (_courseStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(CourseBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.course_id);
if (_courseStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(CourseBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.name))
{
throw new ArgumentNullException("Нет названия направления!",
nameof(model.name));
}
_logger.LogInformation("Course. CourseName:{CourseName}. Id: { Id}", model.name, model.course_id);
var element = _courseStorage.GetElement(new CourseSearchModel
{
name = model.name
});
if (element != null && element.course_id != model.course_id)
{
throw new InvalidOperationException("Направление с таким названием уже есть");
}
}
}
}

View File

@ -0,0 +1,129 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentBusinessLogic
{
public class ExamPointsLogic : IExamPointsLogic
{
private readonly ILogger _logger;
private readonly IExamPointsStorage _examPointsStorage;
public ExamPointsLogic(ILogger<ExamPointsLogic> logger, IExamPointsStorage
examPointsStorage)
{
_logger = logger;
_examPointsStorage = examPointsStorage;
}
public List<ExamPointsViewModel>? ReadList(ExamPointsSearchModel? model)
{
_logger.LogInformation("ReadList. Id:{ Id}", model?.exampoints_id);
var list = model == null ? _examPointsStorage.GetFullList() :
_examPointsStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public ExamPointsViewModel? ReadElement(ExamPointsSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement .Id:{ Id}", model.exampoints_id);
var element = _examPointsStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(ExamPointsBindingModel model)
{
CheckModel(model);
if (_examPointsStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public IExamPointsModel Create(ExamPointsBindingModel model, bool returnTypeIsModel)
{
if (returnTypeIsModel)
{
CheckModel(model);
if (_examPointsStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return null;
}
var list = _examPointsStorage.GetFullList();
return list[list.Count - 1];
}
return null;
}
public bool Update(ExamPointsBindingModel model)
{
CheckModel(model);
if (_examPointsStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(ExamPointsBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_examPointsStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(ExamPointsBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (model.FirstExamPoints == 0)
{
throw new ArgumentNullException("Нет баллов за первый экзамен",
nameof(model.FirstExamPoints));
}
if (model.SecondExamPoints == 0)
{
throw new ArgumentNullException("Нет баллов за второй экзамен",
nameof(model.SecondExamPoints));
}
if (model.ThirdExamPoints == 0)
{
throw new ArgumentNullException("Нет баллов за третий экзамен",
nameof(model.ThirdExamPoints));
}
_logger.LogInformation("ExamPoints. FirstExamPoints: {FirstExamPoints}. " +
"SecondExamPoints: {SecondExamPoints}. ThirdExamPoints: {ThirdExamPoints}. AddPoints: {AddPoints}. Summary: {Summary}" +
"Id: { Id}",
model.FirstExamPoints, model.SecondExamPoints, model.ThirdExamPoints,
model.AddPoints, model.Summary, model.Id);
}
}
}

View File

@ -0,0 +1,108 @@
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using Microsoft.Extensions.Logging;
namespace StudentEnrollmentBusinessLogic
{
public class FacultyLogic : IFacultyLogic
{
private readonly IFacultyStorage _facultyStorage;
private readonly ILogger _logger;
public FacultyLogic(IFacultyStorage facultyStorage, ILogger<FacultyLogic> logger)
{
_facultyStorage = facultyStorage;
_logger = logger;
}
public List<FacultyViewModel>? ReadList(FacultySearchModel? model)
{
_logger.LogInformation("ReadList. FacultyName:{FacultyName}.Id:{ Id}", model?.name, model?.faculty_id);
var list = model == null ? _facultyStorage.GetFullList() :
_facultyStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public FacultyViewModel? ReadElement(FacultySearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadElement. FacultyName:{FacultyName}.Id:{ Id}", model.name, model.faculty_id);
var element = _facultyStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(FacultyBindingModel model)
{
CheckModel(model);
if (_facultyStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(FacultyBindingModel model)
{
CheckModel(model);
if (_facultyStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(FacultyBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_facultyStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(FacultyBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.FacultyName))
{
throw new ArgumentNullException("Нет названия факультета!",
nameof(model.FacultyName));
}
_logger.LogInformation("Faculty. FacultyName:{FacultyName}. Id: { Id}", model.FacultyName, model.Id);
var element = _facultyStorage.GetElement(new FacultySearchModel
{
name = model.FacultyName,
}); ;
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Факультет с таким же названием уже есть");
}
}
}
}

View File

@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StudentEnrollmentContracts\StudentEnrollmentContracts.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,119 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentBusinessLogic
{
public class StudentLogic : IStudentLogic
{
private readonly ILogger _logger;
private readonly IStudentStorage _studentStorage;
public StudentLogic(ILogger<StudentLogic> logger, IStudentStorage studentStorage)
{
_logger = logger;
_studentStorage = studentStorage;
}
public List<StudentViewModel>? ReadList(StudentSearchModel? model)
{
_logger.LogInformation("ReadList. TIN: {TIN}. Id:{Id}", model?.tin, model?.student_id);
var list = model == null ? _studentStorage.GetFullList() : _studentStorage.GetFilteredList(model);
if (list == null)
{
_logger.LogWarning("ReadList return null list");
return null;
}
_logger.LogInformation("ReadList. Count:{Count}", list.Count);
return list;
}
public StudentViewModel? ReadElement(StudentSearchModel model)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
_logger.LogInformation("ReadList. TIN: {TIN}. Id:{Id}", model?.tin, model?.student_id);
var element = _studentStorage.GetElement(model);
if (element == null)
{
_logger.LogWarning("ReadElement element not found");
return null;
}
_logger.LogInformation("ReadElement find. Id:{Id}", element.Id);
return element;
}
public bool Create(StudentBindingModel model)
{
CheckModel(model);
if (_studentStorage.Insert(model) == null)
{
_logger.LogWarning("Insert operation failed");
return false;
}
return true;
}
public bool Update(StudentBindingModel model)
{
CheckModel(model);
if (_studentStorage.Update(model) == null)
{
_logger.LogWarning("Update operation failed");
return false;
}
return true;
}
public bool Delete(StudentBindingModel model)
{
CheckModel(model, false);
_logger.LogInformation("Delete. Id:{Id}", model.Id);
if (_studentStorage.Delete(model) == null)
{
_logger.LogWarning("Delete operation failed");
return false;
}
return true;
}
private void CheckModel(StudentBindingModel model, bool withParams = true)
{
if (model == null)
{
throw new ArgumentNullException(nameof(model));
}
if (!withParams)
{
return;
}
if (string.IsNullOrEmpty(model.LastName))
{
throw new ArgumentNullException("Нет фамилии студента!", nameof(model.LastName));
}
if (string.IsNullOrEmpty(model.FirstName))
{
throw new ArgumentNullException("Нет имени студента!", nameof(model.FirstName));
}
if (model.TIN == 0)
{
throw new ArgumentNullException("Нет ИНН студента!", nameof(model.TIN));
}
if (string.IsNullOrEmpty(model.Email))
{
throw new ArgumentNullException("Нет почты студента!", nameof(model.Email));
}
if (model.StudentCourse.Count == 0)
{
throw new ArgumentNullException("У студента должны быть баллы за экзамены!", nameof(model.StudentCourse));
}
_logger.LogInformation("Student. LastName: {LastName}, FirstName: {FirstName}, MiddleName: {MiddleName}, TIN: {TIN}, Email: {Email}, Id: {Id}", model.LastName, model.FirstName, model.MiddleName, model.TIN, model.Email, model.Id);
var element = _studentStorage.GetElement(new StudentSearchModel
{
tin = model.TIN
});
if (element != null && element.Id != model.Id)
{
throw new InvalidOperationException("Студент с таким ИНН уже есть");
}
}
}
}

View File

@ -0,0 +1,11 @@
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentContracts.BindingModels
{
public class CourseBindingModel : ICourseModel
{
public int course_id { get; set; }
public string name { get; set; } = string.Empty;
public int facultyid { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentContracts.BindingModels
{
public class ExamPointsBindingModel : IExamPointsModel
{
public int Id { get; set; }
public int FirstExamPoints { get; set; }
public int SecondExamPoints { get; set; }
public int ThirdExamPoints { get; set; }
public int AddPoints { get; set; } = 0;
public int Summary { get; set; }
}
}

View File

@ -0,0 +1,10 @@
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentContracts.BindingModels
{
public class FacultyBindingModel : IFacultyModel
{
public int Id { get; set; }
public string FacultyName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,20 @@
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentContracts.BindingModels
{
public class StudentBindingModel : IStudentModel
{
public int Id { get; set; }
public string FirstName { get; set; } = string.Empty;
public string LastName { get; set; } = string.Empty;
public string MiddleName { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public long TIN { get; set; }
public int ExamPointsId { get; set; }
public Dictionary<int, ICourseModel> StudentCourse
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,15 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.BusinessLogicContracts
{
public interface ICourseLogic
{
List<CourseViewModel>? ReadList(CourseSearchModel? model);
CourseViewModel? ReadElement(CourseSearchModel model);
bool Create(CourseBindingModel model);
bool Update(CourseBindingModel model);
bool Delete(CourseBindingModel model);
}
}

View File

@ -0,0 +1,17 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentContracts.BusinessLogicContracts
{
public interface IExamPointsLogic
{
List<ExamPointsViewModel>? ReadList(ExamPointsSearchModel? model);
ExamPointsViewModel? ReadElement(ExamPointsSearchModel model);
bool Create(ExamPointsBindingModel model);
IExamPointsModel Create(ExamPointsBindingModel model, bool returnTypeIsModel);
bool Update(ExamPointsBindingModel model);
bool Delete(ExamPointsBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.BusinessLogicContracts
{
public interface IFacultyLogic
{
List<FacultyViewModel>? ReadList(FacultySearchModel? model);
FacultyViewModel? ReadElement(FacultySearchModel model);
bool Create(FacultyBindingModel model);
bool Update(FacultyBindingModel model);
bool Delete(FacultyBindingModel model);
}
}

View File

@ -0,0 +1,15 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.BusinessLogicContracts
{
public interface IStudentLogic
{
List<StudentViewModel>? ReadList(StudentSearchModel? model);
StudentViewModel? ReadElement(StudentSearchModel model);
bool Create(StudentBindingModel model);
bool Update(StudentBindingModel model);
bool Delete(StudentBindingModel model);
}
}

View File

@ -0,0 +1,8 @@
namespace StudentEnrollmentContracts.SearchModels
{
public class CourseSearchModel
{
public int? course_id { get; set; }
public string? name { get; set; }
}
}

View File

@ -0,0 +1,7 @@
namespace StudentEnrollmentContracts.SearchModels
{
public class ExamPointsSearchModel
{
public int? exampoints_id { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace StudentEnrollmentContracts.SearchModels
{
public class FacultySearchModel
{
public int? faculty_id { get; set; }
public string? name { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace StudentEnrollmentContracts.SearchModels
{
public class StudentSearchModel
{
public int? student_id { get; set; }
public long? tin { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.StorageContracts
{
public interface ICourseStorage
{
List<CourseViewModel> GetFullList();
List<CourseViewModel> GetFilteredList(CourseSearchModel model);
CourseViewModel? GetElement(CourseSearchModel model);
CourseViewModel? Insert(CourseBindingModel model);
CourseViewModel? Update(CourseBindingModel model);
CourseViewModel? Delete(CourseBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.StorageContracts
{
public interface IExamPointsStorage
{
List<ExamPointsViewModel> GetFullList();
List<ExamPointsViewModel> GetFilteredList(ExamPointsSearchModel model);
ExamPointsViewModel? GetElement(ExamPointsSearchModel model);
ExamPointsViewModel? Insert(ExamPointsBindingModel model);
ExamPointsViewModel? Update(ExamPointsBindingModel model);
ExamPointsViewModel? Delete(ExamPointsBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.StorageContracts
{
public interface IFacultyStorage
{
List<FacultyViewModel> GetFullList();
List<FacultyViewModel> GetFilteredList(FacultySearchModel model);
FacultyViewModel? GetElement(FacultySearchModel model);
FacultyViewModel? Insert(FacultyBindingModel model);
FacultyViewModel? Update(FacultyBindingModel model);
FacultyViewModel? Delete(FacultyBindingModel model);
}
}

View File

@ -0,0 +1,16 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.ViewModels;
namespace StudentEnrollmentContracts.StorageContracts
{
public interface IStudentStorage
{
List<StudentViewModel> GetFullList();
List<StudentViewModel> GetFilteredList(StudentSearchModel model);
StudentViewModel? GetElement(StudentSearchModel model);
StudentViewModel? Insert(StudentBindingModel model);
StudentViewModel? Update(StudentBindingModel model);
StudentViewModel? Delete(StudentBindingModel model);
}
}

View File

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

View File

@ -0,0 +1,15 @@
using StudentEnrollmentDataModels.Models;
using System.ComponentModel;
namespace StudentEnrollmentContracts.ViewModels
{
public class CourseViewModel : ICourseModel
{
public int course_id { get; set; }
[DisplayName("Название направления")]
public string name { get; set; } = string.Empty;
[DisplayName("Название факультета")]
public string FacultyName { get; set; } = string.Empty;
public int facultyid { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using StudentEnrollmentDataModels.Models;
using System.ComponentModel;
namespace StudentEnrollmentContracts.ViewModels
{
public class ExamPointsViewModel : IExamPointsModel
{
public int Id { get; set; }
[DisplayName("Баллы за первый экзамен")]
public int FirstExamPoints { get; set; }
[DisplayName("Баллы за второй экзамен")]
public int SecondExamPoints { get; set; }
[DisplayName("Баллы за третий экзамен")]
public int ThirdExamPoints { get; set; }
[DisplayName("Дополнительные баллы")]
public int AddPoints { get; set; } = 0;
[DisplayName("Сумма баллов")]
public int Summary { get; set; }
}
}

View File

@ -0,0 +1,12 @@
using StudentEnrollmentDataModels.Models;
using System.ComponentModel;
namespace StudentEnrollmentContracts.ViewModels
{
public class FacultyViewModel : IFacultyModel
{
public int Id { get; set; }
[DisplayName("Название факультета")]
public string FacultyName { get; set; } = string.Empty;
}
}

View File

@ -0,0 +1,28 @@
using StudentEnrollmentDataModels.Models;
using System.ComponentModel;
namespace StudentEnrollmentContracts.ViewModels
{
public class StudentViewModel : IStudentModel
{
public int Id { get; set; }
[DisplayName("Имя")]
public string FirstName { get; set; } = string.Empty;
[DisplayName("Фамилия")]
public string LastName { get; set; } = string.Empty;
[DisplayName("Отчество")]
public string MiddleName { get; set; } = string.Empty;
[DisplayName("Почта")]
public string Email { get; set; } = string.Empty;
[DisplayName("ИНН")]
public long TIN { get; set; }
public int ExamPointsId { get; set; }
[DisplayName("Суммарное количество баллов")]
public int Summary { get; set; }
public Dictionary<int, ICourseModel> StudentCourse
{
get;
set;
} = new();
}
}

View File

@ -0,0 +1,7 @@
namespace StudentEnrollmentDataModels
{
public interface IId
{
int Id { get; }
}
}

View File

@ -0,0 +1,9 @@
namespace StudentEnrollmentDataModels.Models
{
public interface ICourseModel //: IId
{
int course_id { get; }
string name { get; }
int facultyid { get; }
}
}

View File

@ -0,0 +1,11 @@
namespace StudentEnrollmentDataModels.Models
{
public interface IExamPointsModel : IId
{
int FirstExamPoints { get; }
int SecondExamPoints { get; }
int ThirdExamPoints { get; }
int AddPoints { get; }
int Summary { get; }
}
}

View File

@ -0,0 +1,7 @@
namespace StudentEnrollmentDataModels.Models
{
public interface IFacultyModel : IId
{
string FacultyName { get; }
}
}

View File

@ -0,0 +1,13 @@
namespace StudentEnrollmentDataModels.Models
{
public interface IStudentModel : IId
{
string LastName { get; }
string FirstName { get; }
string MiddleName { get; }
string Email { get; }
long TIN { get; }
int ExamPointsId { get; }
Dictionary<int, ICourseModel> StudentCourse { get; }
}
}

View File

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

View File

@ -0,0 +1,85 @@
using Microsoft.EntityFrameworkCore;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDatabaseImplement.Models;
namespace StudentEnrollmentDatabaseImplement.Implements
{
public class CourseStorage : ICourseStorage
{
public List<CourseViewModel> GetFullList()
{
using var context = new StudentEnrollmentDatabase();
return context.course
.Include(x => x.Faculty)
.Select(x => x.GetViewModel)
.ToList();
}
public List<CourseViewModel> GetFilteredList(CourseSearchModel model)
{
if (string.IsNullOrEmpty(model.name))
{
return new();
}
using var context = new StudentEnrollmentDatabase();
return context.course
.Include(x => x.Faculty)
.Where(x => (model.course_id.HasValue && x.course_id == model.course_id) || (string.IsNullOrEmpty(model.name) && x.name == model.name))
.Select(x => x.GetViewModel)
.ToList();
}
public CourseViewModel? GetElement(CourseSearchModel model)
{
if (string.IsNullOrEmpty(model.name) && !model.course_id.HasValue)
{
return null;
}
using var context = new StudentEnrollmentDatabase();
return context.course
.Include(x => x.Faculty)
.FirstOrDefault(x => (model.course_id.HasValue && x.course_id == model.course_id) || (string.IsNullOrEmpty(model.name) && x.name == model.name))?
.GetViewModel;
}
public CourseViewModel? Insert(CourseBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var newCourse = Course.Create(model);
if (newCourse == null)
{
return null;
}
context.course.Add(newCourse);
context.SaveChanges();
return context.course
.Include(x => x.Faculty)
.FirstOrDefault(x => x.course_id == newCourse.course_id)?
.GetViewModel;
}
public CourseViewModel? Update(CourseBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var course = context.course.Include(x => x.Faculty).FirstOrDefault(x => x.course_id == model.course_id);
if (course == null)
{
return null;
}
course.Update(model);
context.SaveChanges();
return course.GetViewModel;
}
public CourseViewModel? Delete(CourseBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var element = context.course.Include(x => x.Faculty).FirstOrDefault(rec => rec.course_id == model.course_id);
if (element != null)
{
context.course.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDatabaseImplement.Models;
namespace StudentEnrollmentDatabaseImplement.Implements
{
public class ExamPointsStorage : IExamPointsStorage
{
public List<ExamPointsViewModel> GetFullList()
{
using var context = new StudentEnrollmentDatabase();
return context.exampoints
.Select(x => x.GetViewModel)
.ToList();
}
public List<ExamPointsViewModel> GetFilteredList(ExamPointsSearchModel model)
{
if (!model.exampoints_id.HasValue)
{
return new();
}
using var context = new StudentEnrollmentDatabase();
return context.exampoints
.Where(x => model.exampoints_id.HasValue && x.exampoints_id == model.exampoints_id)
.Select(x => x.GetViewModel)
.ToList();
}
public ExamPointsViewModel? GetElement(ExamPointsSearchModel model)
{
if (!model.exampoints_id.HasValue)
{
return null;
}
using var context = new StudentEnrollmentDatabase();
return context.exampoints
.FirstOrDefault(x => model.exampoints_id.HasValue && x.exampoints_id == model.exampoints_id)?
.GetViewModel;
}
public ExamPointsViewModel? Insert(ExamPointsBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var newExamPoints = ExamPoints.Create(model);
if (newExamPoints == null)
{
return null;
}
context.exampoints.Add(newExamPoints);
context.SaveChanges();
return newExamPoints.GetViewModel;
}
public ExamPointsViewModel? Update(ExamPointsBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var examPoints = context.exampoints.FirstOrDefault(x => x.exampoints_id == model.Id);
if (examPoints == null)
{
return null;
}
examPoints.Update(model);
context.SaveChanges();
return examPoints.GetViewModel;
}
public ExamPointsViewModel? Delete(ExamPointsBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var element = context.exampoints.FirstOrDefault(rec => rec.exampoints_id == model.Id);
if (element != null)
{
context.exampoints.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.EntityFrameworkCore;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDatabaseImplement.Models;
namespace StudentEnrollmentDatabaseImplement.Implements
{
public class FacultyStorage : IFacultyStorage
{
public List<FacultyViewModel> GetFullList()
{
using var context = new StudentEnrollmentDatabase();
return context.faculty
.Select(x => x.GetViewModel)
.ToList();
}
public List<FacultyViewModel> GetFilteredList(FacultySearchModel model)
{
if (string.IsNullOrEmpty(model.name))
{
return new();
}
using var context = new StudentEnrollmentDatabase();
return context.faculty
.Where(x => (model.faculty_id.HasValue && x.faculty_id == model.faculty_id) || (string.IsNullOrEmpty(model.name) && x.name == model.name))
.Select(x => x.GetViewModel)
.ToList();
}
public FacultyViewModel? GetElement(FacultySearchModel model)
{
if (string.IsNullOrEmpty(model.name) && !model.faculty_id.HasValue)
{
return null;
}
using var context = new StudentEnrollmentDatabase();
return context.faculty
.FirstOrDefault(x => (model.faculty_id.HasValue && x.faculty_id == model.faculty_id) || (string.IsNullOrEmpty(model.name) && x.name == model.name))?
.GetViewModel;
}
public FacultyViewModel? Insert(FacultyBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var newFaculty = Faculty.Create(model);
if (newFaculty == null)
{
return null;
}
context.faculty.Add(newFaculty);
context.SaveChanges();
return newFaculty.GetViewModel;
}
public FacultyViewModel? Update(FacultyBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var faculty = context.faculty.FirstOrDefault(x => x.faculty_id == model.Id);
if (faculty == null)
{
return null;
}
faculty.Update(model);
context.SaveChanges();
return faculty.GetViewModel;
}
public FacultyViewModel? Delete(FacultyBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var element = context.faculty.FirstOrDefault(rec => rec.faculty_id == model.Id);
if (element != null)
{
context.faculty.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,112 @@
using Microsoft.EntityFrameworkCore;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDatabaseImplement.Models;
namespace StudentEnrollmentDatabaseImplement.Implements
{
public class StudentStorage : IStudentStorage
{
public List<StudentViewModel> GetFullList()
{
using var context = new StudentEnrollmentDatabase();
return context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.Select(x => x.GetViewModel)
.ToList();
}
public List<StudentViewModel> GetFilteredList(StudentSearchModel model)
{
if (model.tin == 0)
{
return new();
}
using var context = new StudentEnrollmentDatabase();
return context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.Where(x => (model.student_id.HasValue && x.student_id == model.student_id) || (model.tin == 0 && x.tin == model.tin))
.Select(x => x.GetViewModel)
.ToList();
}
public StudentViewModel? GetElement(StudentSearchModel model)
{
if (model.tin == 0 && !model.student_id.HasValue)
{
return null;
}
using var context = new StudentEnrollmentDatabase();
return context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.FirstOrDefault(x => (model.student_id.HasValue && x.student_id == model.student_id) || (model.tin == 0 && x.tin == model.tin))?
.GetViewModel;
}
public StudentViewModel? Insert(StudentBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var newStudent = Student.Create(context, model);
if (newStudent == null)
{
return null;
}
context.student.Add(newStudent);
context.SaveChanges();
return context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.FirstOrDefault(x => x.student_id == newStudent.student_id)?.GetViewModel;
}
public StudentViewModel? Update(StudentBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
using var transaction = context.Database.BeginTransaction();
try
{
var student = context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.FirstOrDefault(x => x.student_id == model.Id);
if (student == null)
{
return null;
}
student.Update(model);
context.SaveChanges();
student.UpdateCourses(context, model);
context.SaveChanges();
transaction.Commit();
return student.GetViewModel;
}
catch
{
transaction.Rollback();
throw;
}
}
public StudentViewModel? Delete(StudentBindingModel model)
{
using var context = new StudentEnrollmentDatabase();
var element = context.student
.Include(x => x.ExamPoints)
.Include(x => x.Courses)
.ThenInclude(x => x.Course)
.FirstOrDefault(rec => rec.student_id == model.Id);
if (element != null)
{
context.student.Remove(element);
context.SaveChanges();
return element.GetViewModel;
}
return null;
}
}
}

View File

@ -0,0 +1,213 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using StudentEnrollmentDatabaseImplement;
#nullable disable
namespace StudentEnrollmentDatabaseImplement.Migrations
{
[DbContext(typeof(StudentEnrollmentDatabase))]
[Migration("20240507161008_InitCreate")]
partial class InitCreate
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.18")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.Property<int>("course_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("course_id"));
b.Property<int>("facultyid")
.HasColumnType("integer");
b.Property<string>("name")
.IsRequired()
.HasColumnType("text");
b.HasKey("course_id");
b.HasIndex("facultyid");
b.ToTable("course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.ExamPoints", b =>
{
b.Property<int>("exampoints_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("exampoints_id"));
b.Property<int>("addpoints")
.HasColumnType("integer");
b.Property<int>("firstexampoints")
.HasColumnType("integer");
b.Property<int>("secondexampoints")
.HasColumnType("integer");
b.Property<int>("summary")
.HasColumnType("integer");
b.Property<int>("thirdexampoints")
.HasColumnType("integer");
b.HasKey("exampoints_id");
b.ToTable("exampoints");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Faculty", b =>
{
b.Property<int>("faculty_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("faculty_id"));
b.Property<string>("name")
.IsRequired()
.HasColumnType("text");
b.HasKey("faculty_id");
b.ToTable("faculty");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.Property<int>("student_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("student_id"));
b.Property<string>("email")
.IsRequired()
.HasColumnType("text");
b.Property<int>("exampointsid")
.HasColumnType("integer");
b.Property<string>("firstname")
.IsRequired()
.HasColumnType("text");
b.Property<string>("lastname")
.IsRequired()
.HasColumnType("text");
b.Property<string>("middlename")
.IsRequired()
.HasColumnType("text");
b.Property<long>("tin")
.HasColumnType("bigint");
b.HasKey("student_id");
b.HasIndex("exampointsid");
b.ToTable("student");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.StudentCourse", b =>
{
b.Property<int>("student_course_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("student_course_id"));
b.Property<int>("course_id")
.HasColumnType("integer");
b.Property<int>("courseid")
.HasColumnType("integer");
b.Property<int>("student_id")
.HasColumnType("integer");
b.Property<int>("studentid")
.HasColumnType("integer");
b.HasKey("student_course_id");
b.HasIndex("course_id");
b.HasIndex("student_id");
b.ToTable("student_course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Faculty", "Faculty")
.WithMany()
.HasForeignKey("facultyid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Faculty");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.ExamPoints", "ExamPoints")
.WithMany()
.HasForeignKey("exampointsid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ExamPoints");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.StudentCourse", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Course", "Course")
.WithMany("student_course")
.HasForeignKey("course_id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Student", "Student")
.WithMany("Courses")
.HasForeignKey("student_id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Course");
b.Navigation("Student");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.Navigation("student_course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.Navigation("Courses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,156 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace StudentEnrollmentDatabaseImplement.Migrations
{
/// <inheritdoc />
public partial class InitCreate : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "exampoints",
columns: table => new
{
exampoints_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
firstexampoints = table.Column<int>(type: "integer", nullable: false),
secondexampoints = table.Column<int>(type: "integer", nullable: false),
thirdexampoints = table.Column<int>(type: "integer", nullable: false),
addpoints = table.Column<int>(type: "integer", nullable: false),
summary = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_exampoints", x => x.exampoints_id);
});
migrationBuilder.CreateTable(
name: "faculty",
columns: table => new
{
faculty_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_faculty", x => x.faculty_id);
});
migrationBuilder.CreateTable(
name: "student",
columns: table => new
{
student_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
firstname = table.Column<string>(type: "text", nullable: false),
lastname = table.Column<string>(type: "text", nullable: false),
middlename = table.Column<string>(type: "text", nullable: false),
email = table.Column<string>(type: "text", nullable: false),
tin = table.Column<long>(type: "bigint", nullable: false),
exampointsid = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_student", x => x.student_id);
table.ForeignKey(
name: "FK_student_exampoints_exampointsid",
column: x => x.exampointsid,
principalTable: "exampoints",
principalColumn: "exampoints_id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "course",
columns: table => new
{
course_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
name = table.Column<string>(type: "text", nullable: false),
facultyid = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_course", x => x.course_id);
table.ForeignKey(
name: "FK_course_faculty_facultyid",
column: x => x.facultyid,
principalTable: "faculty",
principalColumn: "faculty_id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "student_course",
columns: table => new
{
student_course_id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
studentid = table.Column<int>(type: "integer", nullable: false),
courseid = table.Column<int>(type: "integer", nullable: false),
student_id = table.Column<int>(type: "integer", nullable: false),
course_id = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_student_course", x => x.student_course_id);
table.ForeignKey(
name: "FK_student_course_course_course_id",
column: x => x.course_id,
principalTable: "course",
principalColumn: "course_id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_student_course_student_student_id",
column: x => x.student_id,
principalTable: "student",
principalColumn: "student_id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_course_facultyid",
table: "course",
column: "facultyid");
migrationBuilder.CreateIndex(
name: "IX_student_exampointsid",
table: "student",
column: "exampointsid");
migrationBuilder.CreateIndex(
name: "IX_student_course_course_id",
table: "student_course",
column: "course_id");
migrationBuilder.CreateIndex(
name: "IX_student_course_student_id",
table: "student_course",
column: "student_id");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "student_course");
migrationBuilder.DropTable(
name: "course");
migrationBuilder.DropTable(
name: "student");
migrationBuilder.DropTable(
name: "faculty");
migrationBuilder.DropTable(
name: "exampoints");
}
}
}

View File

@ -0,0 +1,210 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using StudentEnrollmentDatabaseImplement;
#nullable disable
namespace StudentEnrollmentDatabaseImplement.Migrations
{
[DbContext(typeof(StudentEnrollmentDatabase))]
partial class StudentEnrollmentDatabaseModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "7.0.18")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.Property<int>("course_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("course_id"));
b.Property<int>("facultyid")
.HasColumnType("integer");
b.Property<string>("name")
.IsRequired()
.HasColumnType("text");
b.HasKey("course_id");
b.HasIndex("facultyid");
b.ToTable("course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.ExamPoints", b =>
{
b.Property<int>("exampoints_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("exampoints_id"));
b.Property<int>("addpoints")
.HasColumnType("integer");
b.Property<int>("firstexampoints")
.HasColumnType("integer");
b.Property<int>("secondexampoints")
.HasColumnType("integer");
b.Property<int>("summary")
.HasColumnType("integer");
b.Property<int>("thirdexampoints")
.HasColumnType("integer");
b.HasKey("exampoints_id");
b.ToTable("exampoints");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Faculty", b =>
{
b.Property<int>("faculty_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("faculty_id"));
b.Property<string>("name")
.IsRequired()
.HasColumnType("text");
b.HasKey("faculty_id");
b.ToTable("faculty");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.Property<int>("student_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("student_id"));
b.Property<string>("email")
.IsRequired()
.HasColumnType("text");
b.Property<int>("exampointsid")
.HasColumnType("integer");
b.Property<string>("firstname")
.IsRequired()
.HasColumnType("text");
b.Property<string>("lastname")
.IsRequired()
.HasColumnType("text");
b.Property<string>("middlename")
.IsRequired()
.HasColumnType("text");
b.Property<long>("tin")
.HasColumnType("bigint");
b.HasKey("student_id");
b.HasIndex("exampointsid");
b.ToTable("student");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.StudentCourse", b =>
{
b.Property<int>("student_course_id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("student_course_id"));
b.Property<int>("course_id")
.HasColumnType("integer");
b.Property<int>("courseid")
.HasColumnType("integer");
b.Property<int>("student_id")
.HasColumnType("integer");
b.Property<int>("studentid")
.HasColumnType("integer");
b.HasKey("student_course_id");
b.HasIndex("course_id");
b.HasIndex("student_id");
b.ToTable("student_course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Faculty", "Faculty")
.WithMany()
.HasForeignKey("facultyid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Faculty");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.ExamPoints", "ExamPoints")
.WithMany()
.HasForeignKey("exampointsid")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("ExamPoints");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.StudentCourse", b =>
{
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Course", "Course")
.WithMany("student_course")
.HasForeignKey("course_id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("StudentEnrollmentDatabaseImplement.Models.Student", "Student")
.WithMany("Courses")
.HasForeignKey("student_id")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Course");
b.Navigation("Student");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Course", b =>
{
b.Navigation("student_course");
});
modelBuilder.Entity("StudentEnrollmentDatabaseImplement.Models.Student", b =>
{
b.Navigation("Courses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,50 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace StudentEnrollmentDatabaseImplement.Models
{
public class Course : ICourseModel
{
[Key]
public int course_id { get; private set; }
[Required]
public string name { get; private set; } = string.Empty;
[Required]
public int facultyid { get; set; }
public virtual Faculty Faculty { get; set; }
[ForeignKey("courseid")]
public virtual List<StudentCourse> StudentCourses { get; set; } = new();
public static Course? Create(CourseBindingModel model)
{
if (model == null)
{
return null;
}
return new Course()
{
course_id = model.course_id,
name = model.name,
facultyid = model.facultyid,
};
}
public void Update(CourseBindingModel model)
{
if (model == null)
{
return;
}
name = model.name;
facultyid = model.facultyid;
}
public CourseViewModel GetViewModel => new()
{
course_id = course_id,
name = name,
facultyid = facultyid,
FacultyName = Faculty.name,
};
}
}

View File

@ -0,0 +1,56 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace StudentEnrollmentDatabaseImplement.Models
{
public class ExamPoints //: IExamPointsModel
{
[Key]
public int exampoints_id { get; private set; }
[Required]
public int firstexampoints { get; private set; }
[Required]
public int secondexampoints { get; private set; }
[Required]
public int thirdexampoints { get; private set; }
public int addpoints { get; private set; }
public int summary { get; private set; }
public static ExamPoints? Create(ExamPointsBindingModel model)
{
if (model == null) {
return null;
}
return new ExamPoints()
{
exampoints_id = model.Id,
firstexampoints = model.FirstExamPoints,
secondexampoints = model.SecondExamPoints,
thirdexampoints = model.ThirdExamPoints,
addpoints = model.AddPoints,
summary = model.FirstExamPoints + model.SecondExamPoints + model.ThirdExamPoints + model.AddPoints,
};
}
public void Update(ExamPointsBindingModel model)
{
if (model == null)
{
return;
}
summary -= addpoints;
addpoints = model.AddPoints;
summary += model.AddPoints;
}
public ExamPointsViewModel GetViewModel => new()
{
Id = exampoints_id,
FirstExamPoints = firstexampoints,
SecondExamPoints = secondexampoints,
ThirdExamPoints = thirdexampoints,
AddPoints = addpoints,
Summary = summary,
};
}
}

View File

@ -0,0 +1,38 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
using System.ComponentModel.DataAnnotations;
namespace StudentEnrollmentDatabaseImplement.Models
{
public class Faculty // : IFacultyModel
{
[Key]
public int faculty_id { get; private set; }
[Required]
public string name { get; private set;} = string.Empty;
public static Faculty? Create(FacultyBindingModel model)
{
if (model == null)
return null;
return new Faculty()
{
faculty_id = model.Id,
name = model.FacultyName,
};
}
public void Update(FacultyBindingModel model)
{
if (model == null)
return;
name = model.FacultyName;
}
public FacultyViewModel GetViewModel => new()
{
Id = faculty_id,
FacultyName = name,
};
}
}

View File

@ -0,0 +1,121 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace StudentEnrollmentDatabaseImplement.Models
{
public class Student //: IStudentModel
{
[Key]
public int student_id { get; private set; }
[Required]
public string firstname { get; private set; } = string.Empty;
[Required]
public string lastname { get; private set; } = string.Empty;
public string middlename { get; private set; } = string.Empty;
[Required]
public string email { get; private set; } = string.Empty;
[Required]
public long tin { get; private set; }
[Required]
public int exampointsid { get; private set; }
public virtual ExamPoints ExamPoints { get; private set; }
private Dictionary<int, ICourseModel>? _studentCourse = null;
[NotMapped]
public Dictionary<int, ICourseModel> StudentCourse
{
get
{
if (_studentCourse == null)
{
_studentCourse = Courses
.ToDictionary(x => x.courseid, x => x.Course as ICourseModel);
}
return _studentCourse;
}
}
[ForeignKey("studentid")]
public virtual List<StudentCourse> Courses { get; set; } = new();
public static Student? Create(StudentEnrollmentDatabase context,StudentBindingModel model)
{
if (model == null)
{
return null;
}
var test = model.StudentCourse.Select(x => new StudentCourse
{
Course = context.course.First(y => y.course_id == x.Key)
}
).ToList();
return new Student()
{
student_id = model.Id,
firstname = model.FirstName,
lastname = model.LastName,
middlename = model.MiddleName,
email = model.Email,
tin = model.TIN,
Courses = model.StudentCourse.Select(x => new StudentCourse
{
Course = context.course.First(y => y.course_id == x.Key)
}
).ToList(),
ExamPoints = context.exampoints.First(x => x.exampoints_id == model.ExamPointsId),
};
}
public void Update(StudentBindingModel model)
{
if (model == null)
{
return;
}
firstname = model.FirstName;
lastname = model.LastName;
middlename = model.MiddleName;
tin = model.TIN;
email = model.Email;
}
public StudentViewModel GetViewModel => new()
{
Id = student_id,
FirstName = firstname,
LastName = lastname,
MiddleName = middlename,
TIN = tin,
Email = email,
ExamPointsId = exampointsid,
Summary = ExamPoints.summary,
StudentCourse = StudentCourse,
};
public void UpdateCourses(StudentEnrollmentDatabase context, StudentBindingModel model)
{
var StudentCourses = context.student_course.Where(rec => rec.studentid == model.Id).ToList();
if (StudentCourses != null)
{
context.student_course.RemoveRange(StudentCourses.Where(rec
=> !model.StudentCourse.ContainsKey(rec.courseid)));
context.SaveChanges();
foreach (var updateCourse in StudentCourses)
{
model.StudentCourse.Remove(updateCourse.courseid);
}
context.SaveChanges();
}
var Student = context.student.First(x => x.student_id == student_id);
foreach (var pc in model.StudentCourse)
{
context.student_course.Add(new StudentCourse
{
Student = Student,
Course = context.course.First(x => x.course_id == pc.Key),
});
context.SaveChanges();
}
_studentCourse = null;
}
}
}

View File

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
namespace StudentEnrollmentDatabaseImplement.Models
{
public class StudentCourse
{
[Key]
public int student_course_id { get; set; }
[Required]
public int studentid { get; set; }
[Required]
public int courseid { get; set; }
public virtual Student Student { get; set; } = new();
public virtual Course Course { get; set; } = new();
}
}

View File

@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore;
using StudentEnrollmentDatabaseImplement.Models;
namespace StudentEnrollmentDatabaseImplement
{
public class StudentEnrollmentDatabase : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseNpgsql(@"Host=192.168.56.103;Database=postgres;Username=postgres;Password=postgres");
}
base.OnConfiguring(optionsBuilder);
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDataTimeInfinityConversions", true);
}
public virtual DbSet<Faculty> faculty { get; set; }
public virtual DbSet<Course> course { get; set; }
public virtual DbSet<Student> student { get; set; }
public virtual DbSet<StudentCourse> student_course { get; set; }
public virtual DbSet<ExamPoints> exampoints { get; set; }
}
}

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.18" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.18">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql" Version="7.0.6" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.11" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StudentEnrollmentContracts\StudentEnrollmentContracts.csproj" />
<ProjectReference Include="..\StudentEnrollmentDataModels\StudentEnrollmentDataModels.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,125 @@
namespace StudentEnrollmentView
{
partial class FormCourse
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label1 = new Label();
comboBoxFaculty = new ComboBox();
label2 = new Label();
textBoxName = new TextBox();
buttonCancel = new Button();
buttonAdd = new Button();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(9, 20);
label1.Name = "label1";
label1.Size = new Size(81, 20);
label1.TabIndex = 4;
label1.Text = "Факультет:";
//
// comboBoxFaculty
//
comboBoxFaculty.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxFaculty.FormattingEnabled = true;
comboBoxFaculty.Location = new Point(101, 16);
comboBoxFaculty.Margin = new Padding(3, 4, 3, 4);
comboBoxFaculty.Name = "comboBoxFaculty";
comboBoxFaculty.Size = new Size(285, 28);
comboBoxFaculty.TabIndex = 3;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(9, 64);
label2.Name = "label2";
label2.Size = new Size(80, 20);
label2.TabIndex = 6;
label2.Text = "Название:";
//
// textBoxName
//
textBoxName.Location = new Point(102, 60);
textBoxName.Margin = new Padding(3, 4, 3, 4);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(285, 27);
textBoxName.TabIndex = 5;
//
// buttonCancel
//
buttonCancel.Location = new Point(320, 112);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(98, 31);
buttonCancel.TabIndex = 10;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(215, 112);
buttonAdd.Margin = new Padding(3, 4, 3, 4);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(98, 31);
buttonAdd.TabIndex = 9;
buttonAdd.Text = "Сохранить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonSave_Click;
//
// FormCourse
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(433, 160);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(label2);
Controls.Add(textBoxName);
Controls.Add(label1);
Controls.Add(comboBoxFaculty);
Margin = new Padding(3, 4, 3, 4);
Name = "FormCourse";
Text = "Направление";
Load += FormCourse_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private ComboBox comboBoxFaculty;
private Label label2;
private TextBox textBoxName;
private Button buttonCancel;
private Button buttonAdd;
}
}

View File

@ -0,0 +1,83 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
namespace StudentEnrollmentView
{
public partial class FormCourse : Form
{
private readonly ILogger _logger;
private readonly IFacultyLogic _logicF;
private readonly ICourseLogic _logicC;
private int? _id;
public int Id { set { _id = value; } }
public FormCourse(ILogger<FormCourse> logger, IFacultyLogic logicF, ICourseLogic logicC)
{
InitializeComponent();
_logger = logger;
_logicF = logicF;
_logicC = logicC;
}
private void FormCourse_Load(object sender, EventArgs e)
{
_logger.LogInformation("Загрузка факультетов для направления");
try
{
var _list = _logicF.ReadList(null);
if (_list != null)
{
comboBoxFaculty.DisplayMember = "FacultyName";
comboBoxFaculty.ValueMember = "Id";
comboBoxFaculty.DataSource = _list;
comboBoxFaculty.SelectedItem = null;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки факультетов для направления");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните поле название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (comboBoxFaculty.SelectedValue == null)
{
MessageBox.Show("Выберите факультет", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Создание направления");
try
{
var operationResult = _logicC.Create(new CourseBindingModel
{
course_id = _id ?? 0,
name = textBoxName.Text,
facultyid = Convert.ToInt32(comboBoxFaculty.SelectedValue)
});
if (!operationResult)
{
throw new Exception("Ошибка при создании направления. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка создания направления");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

View File

@ -0,0 +1,114 @@
namespace StudentEnrollmentView
{
partial class FormCourses
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
buttonAdd = new Button();
buttonUpd = new Button();
buttonDel = new Button();
buttonRef = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(12, 12);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(240, 426);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(283, 24);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(103, 28);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpd
//
buttonUpd.Location = new Point(283, 58);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(103, 28);
buttonUpd.TabIndex = 2;
buttonUpd.Text = "Изменить";
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonDel
//
buttonDel.Location = new Point(283, 92);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(103, 28);
buttonDel.TabIndex = 3;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonRef
//
buttonRef.Location = new Point(283, 126);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(103, 28);
buttonRef.TabIndex = 4;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += ButtonRef_Click;
//
// FormCourses
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(438, 450);
Controls.Add(buttonRef);
Controls.Add(buttonDel);
Controls.Add(buttonUpd);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormCourses";
Text = "Направления";
Load += FormCourses_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpd;
private Button buttonDel;
private Button buttonRef;
}
}

View File

@ -0,0 +1,101 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
namespace StudentEnrollmentView
{
public partial class FormCourses : Form
{
private readonly ILogger _logger;
private readonly ICourseLogic _logic;
public FormCourses(ILogger<FormCourses> logger, ICourseLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormCourses_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["course_id"].Visible = false;
dataGridView.Columns["facultyid"].Visible = false;
}
_logger.LogInformation("Загрузка направлений");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки направлений");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCourse));
if (service is FormCourse form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormCourse));
if (service is FormCourse form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["course_id"].Value);
_logger.LogInformation("Удаление направления");
try
{
if (!_logic.Delete(new CourseBindingModel
{
course_id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления направления");
MessageBox.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@ -0,0 +1,163 @@
namespace StudentEnrollmentView
{
partial class FormExamPoints
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label2 = new Label();
textBoxFirstExamPoints = new TextBox();
label1 = new Label();
textBoxSecondExamPoints = new TextBox();
label3 = new Label();
textBoxThirdExamPoints = new TextBox();
label4 = new Label();
textBoxAddPoints = new TextBox();
buttonCancel = new Button();
buttonSave = new Button();
SuspendLayout();
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(10, 23);
label2.Name = "label2";
label2.Size = new Size(102, 15);
label2.TabIndex = 7;
label2.Text = "Первый экзамен:";
//
// textBoxFirstExamPoints
//
textBoxFirstExamPoints.Location = new Point(158, 21);
textBoxFirstExamPoints.Name = "textBoxFirstExamPoints";
textBoxFirstExamPoints.Size = new Size(250, 23);
textBoxFirstExamPoints.TabIndex = 6;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(10, 59);
label1.Name = "label1";
label1.Size = new Size(98, 15);
label1.TabIndex = 9;
label1.Text = "Второй экзамен:";
//
// textBoxSecondExamPoints
//
textBoxSecondExamPoints.Location = new Point(158, 57);
textBoxSecondExamPoints.Name = "textBoxSecondExamPoints";
textBoxSecondExamPoints.Size = new Size(250, 23);
textBoxSecondExamPoints.TabIndex = 8;
//
// label3
//
label3.AutoSize = true;
label3.Location = new Point(10, 98);
label3.Name = "label3";
label3.Size = new Size(96, 15);
label3.TabIndex = 11;
label3.Text = "Третий экзамен:";
//
// textBoxThirdExamPoints
//
textBoxThirdExamPoints.Location = new Point(158, 96);
textBoxThirdExamPoints.Name = "textBoxThirdExamPoints";
textBoxThirdExamPoints.Size = new Size(250, 23);
textBoxThirdExamPoints.TabIndex = 10;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(10, 137);
label4.Name = "label4";
label4.Size = new Size(74, 15);
label4.TabIndex = 13;
label4.Text = "Доп. баллы:";
//
// textBoxAddPoints
//
textBoxAddPoints.Location = new Point(158, 135);
textBoxAddPoints.Name = "textBoxAddPoints";
textBoxAddPoints.Size = new Size(250, 23);
textBoxAddPoints.TabIndex = 12;
//
// buttonCancel
//
buttonCancel.Location = new Point(308, 194);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(104, 28);
buttonCancel.TabIndex = 15;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(198, 194);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(104, 28);
buttonSave.TabIndex = 14;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// FormExamPoints
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(432, 231);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(label4);
Controls.Add(textBoxAddPoints);
Controls.Add(label3);
Controls.Add(textBoxThirdExamPoints);
Controls.Add(label1);
Controls.Add(textBoxSecondExamPoints);
Controls.Add(label2);
Controls.Add(textBoxFirstExamPoints);
Margin = new Padding(3, 2, 3, 2);
Name = "FormExamPoints";
Text = "Баллы за экзамены";
Load += FormExamPoints_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label2;
private TextBox textBoxFirstExamPoints;
private Label label1;
private TextBox textBoxSecondExamPoints;
private Label label3;
private TextBox textBoxThirdExamPoints;
private Label label4;
private TextBox textBoxAddPoints;
private Button buttonCancel;
private Button buttonSave;
}
}

View File

@ -0,0 +1,106 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentDatabaseImplement.Models;
using StudentEnrollmentDataModels.Models;
using System.Windows.Forms;
namespace StudentEnrollmentView
{
public partial class FormExamPoints : Form
{
public int? Id { get; set; }
public IExamPointsModel ExamPoints { get; set; }
private IExamPointsLogic _logic;
public FormExamPoints(IExamPointsLogic logic)
{
_logic = logic;
InitializeComponent();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFirstExamPoints.Text))
{
MessageBox.Show("Заполните баллы за первый экзамен", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxSecondExamPoints.Text))
{
MessageBox.Show("Заполните баллы за второй экзамен", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxThirdExamPoints.Text))
{
MessageBox.Show("Заполните баллы за третий экзамен", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
try
{
var model = new ExamPointsBindingModel
{
Id = Id ?? 0,
FirstExamPoints = Convert.ToInt32(textBoxFirstExamPoints.Text),
SecondExamPoints = Convert.ToInt32(textBoxSecondExamPoints.Text),
ThirdExamPoints = Convert.ToInt32(textBoxThirdExamPoints.Text),
AddPoints = textBoxAddPoints.Text != string.Empty ? Convert.ToInt32(textBoxAddPoints.Text) : 0,
Summary = CalcSum(),
};
var operationResult = _logic.Create(model, true);
if (operationResult == null)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
ExamPoints = operationResult;
Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private int CalcSum()
{
return Convert.ToInt32(textBoxFirstExamPoints.Text)
+ Convert.ToInt32(textBoxSecondExamPoints.Text)
+ Convert.ToInt32(textBoxThirdExamPoints.Text)
+ (textBoxAddPoints.Text != string.Empty ? Convert.ToInt32(textBoxAddPoints.Text) : 0);
}
private void FormExamPoints_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
if (Id != 0)
{
try
{
var view = _logic.ReadElement(new ExamPointsSearchModel
{
exampoints_id = Id,
});
textBoxFirstExamPoints.Text = view.FirstExamPoints.ToString();
textBoxSecondExamPoints.Text = view.SecondExamPoints.ToString();
textBoxThirdExamPoints.Text = view.ThirdExamPoints.ToString();
textBoxAddPoints.Text = view.AddPoints.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}

View File

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

View File

@ -0,0 +1,114 @@
namespace StudentEnrollmentView
{
partial class FormFaculties
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView = new DataGridView();
buttonAdd = new Button();
buttonUpd = new Button();
buttonDel = new Button();
buttonRef = new Button();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// dataGridView
//
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(12, 12);
dataGridView.Name = "dataGridView";
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(240, 426);
dataGridView.TabIndex = 0;
//
// buttonAdd
//
buttonAdd.Location = new Point(283, 24);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(103, 28);
buttonAdd.TabIndex = 1;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonAdd_Click;
//
// buttonUpd
//
buttonUpd.Location = new Point(283, 58);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(103, 28);
buttonUpd.TabIndex = 2;
buttonUpd.Text = "Изменить";
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += ButtonUpd_Click;
//
// buttonDel
//
buttonDel.Location = new Point(283, 92);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(103, 28);
buttonDel.TabIndex = 3;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += ButtonDel_Click;
//
// buttonRef
//
buttonRef.Location = new Point(283, 126);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(103, 28);
buttonRef.TabIndex = 4;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += ButtonRef_Click;
//
// FormComponents
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(438, 450);
Controls.Add(buttonRef);
Controls.Add(buttonDel);
Controls.Add(buttonUpd);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormFaculties";
Text = "Факультеты";
Load += FormFaculties_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private DataGridView dataGridView;
private Button buttonAdd;
private Button buttonUpd;
private Button buttonDel;
private Button buttonRef;
}
}

View File

@ -0,0 +1,102 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
namespace StudentEnrollmentView
{
public partial class FormFaculties : Form
{
private readonly ILogger _logger;
private readonly IFacultyLogic _logic;
public FormFaculties(ILogger<FormFaculties> logger, IFacultyLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormFaculties_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["FacultyName"].AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
}
_logger.LogInformation("Загрузка факультетов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки факультетов");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void ButtonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFaculty));
if (service is FormFaculty form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void ButtonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormFaculty));
if (service is FormFaculty form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void ButtonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление факультета");
try
{
if (!_logic.Delete(new FacultyBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления факультета");
MessageBox.Show(ex.Message, "Ошибка",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void ButtonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@ -0,0 +1,100 @@
namespace StudentEnrollmentView
{
partial class FormFaculty
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label1 = new Label();
textBoxName = new TextBox();
buttonSave = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(31, 20);
label1.Name = "label1";
label1.Size = new Size(80, 20);
label1.TabIndex = 3;
label1.Text = "Название:";
//
// textBoxName
//
textBoxName.Location = new Point(129, 17);
textBoxName.Margin = new Padding(3, 4, 3, 4);
textBoxName.Name = "textBoxName";
textBoxName.Size = new Size(243, 27);
textBoxName.TabIndex = 2;
//
// buttonSave
//
buttonSave.Location = new Point(184, 73);
buttonSave.Margin = new Padding(3, 4, 3, 4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(95, 31);
buttonSave.TabIndex = 6;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(286, 73);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(86, 31);
buttonCancel.TabIndex = 7;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormFaculty
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(391, 126);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(label1);
Controls.Add(textBoxName);
Margin = new Padding(3, 4, 3, 4);
Name = "FormFaculty";
Text = "Факультет";
Load += FormFaculty_Load;
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label1;
private TextBox textBoxName;
private Button buttonSave;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,79 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
namespace StudentEnrollmentView
{
public partial class FormFaculty : Form
{
private readonly ILogger _logger;
private readonly IFacultyLogic _logic;
private int? _id;
public int Id { set { _id = value; } }
public FormFaculty(ILogger<FormFaculty> logger, IFacultyLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormFaculty_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
try
{
_logger.LogInformation("Получение факультета");
var view = _logic.ReadElement(new FacultySearchModel
{
faculty_id = _id.Value
});
if (view != null)
{
textBoxName.Text = view.FacultyName;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка получения факультета");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxName.Text))
{
MessageBox.Show("Заполните название", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение факультета");
try
{
var model = new FacultyBindingModel
{
Id = _id ?? 0,
FacultyName = textBoxName.Text,
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения факультета");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

View File

@ -0,0 +1,217 @@
namespace StudentEnrollmentView
{
partial class FormMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip1 = new MenuStrip();
справочникиToolStripMenuItem = new ToolStripMenuItem();
факультетыToolStripMenuItem = new ToolStripMenuItem();
направленияToolStripMenuItem = new ToolStripMenuItem();
студентыToolStripMenuItem = new ToolStripMenuItem();
buttonAdd = new Button();
groupBox1 = new GroupBox();
labelDelete = new Label();
buttonDelete = new Button();
labelUpdate = new Label();
buttonUpdate = new Button();
labelGet = new Label();
buttonGet = new Button();
labelAdd = new Label();
menuStrip1.SuspendLayout();
groupBox1.SuspendLayout();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.ImageScalingSize = new Size(20, 20);
menuStrip1.Items.AddRange(new ToolStripItem[] { справочникиToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Padding = new Padding(5, 2, 0, 2);
menuStrip1.Size = new Size(411, 24);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip1";
//
// справочникиToolStripMenuItem
//
справочникиToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { факультетыToolStripMenuItem, направленияToolStripMenuItem, студентыToolStripMenuItem });
справочникиToolStripMenuItem.Name = "справочникиToolStripMenuItem";
справочникиToolStripMenuItem.Size = new Size(94, 20);
справочникиToolStripMenuItem.Text = "Справочники";
//
// факультетыToolStripMenuItem
//
факультетыToolStripMenuItem.Name = акультетыToolStripMenuItem";
факультетыToolStripMenuItem.Size = new Size(148, 22);
факультетыToolStripMenuItem.Text = "Факультеты";
факультетыToolStripMenuItem.Click += факультетыToolStripMenuItem_Click;
//
// направленияToolStripMenuItem
//
направленияToolStripMenuItem.Name = аправленияToolStripMenuItem";
направленияToolStripMenuItem.Size = new Size(148, 22);
направленияToolStripMenuItem.Text = "Направления";
направленияToolStripMenuItem.Click += направленияToolStripMenuItem_Click;
//
// студентыToolStripMenuItem
//
студентыToolStripMenuItem.Name = "студентыToolStripMenuItem";
студентыToolStripMenuItem.Size = new Size(148, 22);
студентыToolStripMenuItem.Text = "Студенты";
студентыToolStripMenuItem.Click += студентыToolStripMenuItem_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(17, 32);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(171, 39);
buttonAdd.TabIndex = 3;
buttonAdd.Text = "Добавить 1000 строк";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// groupBox1
//
groupBox1.Controls.Add(labelDelete);
groupBox1.Controls.Add(buttonDelete);
groupBox1.Controls.Add(labelUpdate);
groupBox1.Controls.Add(buttonUpdate);
groupBox1.Controls.Add(labelGet);
groupBox1.Controls.Add(buttonGet);
groupBox1.Controls.Add(labelAdd);
groupBox1.Controls.Add(buttonAdd);
groupBox1.Location = new Point(12, 37);
groupBox1.Name = "groupBox1";
groupBox1.Size = new Size(382, 275);
groupBox1.TabIndex = 4;
groupBox1.TabStop = false;
groupBox1.Text = "Тесты:";
//
// labelDelete
//
labelDelete.AutoSize = true;
labelDelete.Location = new Point(290, 235);
labelDelete.Name = "labelDelete";
labelDelete.Size = new Size(31, 15);
labelDelete.TabIndex = 10;
labelDelete.Text = "0 мс";
//
// buttonDelete
//
buttonDelete.Location = new Point(17, 223);
buttonDelete.Name = "buttonDelete";
buttonDelete.Size = new Size(171, 39);
buttonDelete.TabIndex = 9;
buttonDelete.Text = "Удаление 1000 строк";
buttonDelete.UseVisualStyleBackColor = true;
buttonDelete.Click += buttonDelete_Click;
//
// labelUpdate
//
labelUpdate.AutoSize = true;
labelUpdate.Location = new Point(290, 171);
labelUpdate.Name = "labelUpdate";
labelUpdate.Size = new Size(31, 15);
labelUpdate.TabIndex = 8;
labelUpdate.Text = "0 мс";
//
// buttonUpdate
//
buttonUpdate.Location = new Point(17, 159);
buttonUpdate.Name = "buttonUpdate";
buttonUpdate.Size = new Size(171, 39);
buttonUpdate.TabIndex = 7;
buttonUpdate.Text = "Обновление 1000 строк";
buttonUpdate.UseVisualStyleBackColor = true;
buttonUpdate.Click += buttonUpdate_Click;
//
// labelGet
//
labelGet.AutoSize = true;
labelGet.Location = new Point(290, 106);
labelGet.Name = "labelGet";
labelGet.Size = new Size(31, 15);
labelGet.TabIndex = 6;
labelGet.Text = "0 мс";
//
// buttonGet
//
buttonGet.Location = new Point(17, 94);
buttonGet.Name = "buttonGet";
buttonGet.Size = new Size(171, 39);
buttonGet.TabIndex = 5;
buttonGet.Text = "Получение 1000 строк";
buttonGet.UseVisualStyleBackColor = true;
buttonGet.Click += buttonGet_Click;
//
// labelAdd
//
labelAdd.AutoSize = true;
labelAdd.Location = new Point(290, 44);
labelAdd.Name = "labelAdd";
labelAdd.Size = new Size(31, 15);
labelAdd.TabIndex = 4;
labelAdd.Text = "0 мс";
//
// FormMain
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(411, 325);
Controls.Add(groupBox1);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Margin = new Padding(3, 2, 3, 2);
Name = "FormMain";
Text = "Списки студентов на зачисление";
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
groupBox1.ResumeLayout(false);
groupBox1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip1;
private ToolStripMenuItem справочникиToolStripMenuItem;
private ToolStripMenuItem факультетыToolStripMenuItem;
private ToolStripMenuItem направленияToolStripMenuItem;
private ToolStripMenuItem студентыToolStripMenuItem;
private Button buttonAdd;
private GroupBox groupBox1;
private Label labelAdd;
private Label labelDelete;
private Button buttonDelete;
private Label labelUpdate;
private Button buttonUpdate;
private Label labelGet;
private Button buttonGet;
}
}

View File

@ -0,0 +1,111 @@
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
namespace StudentEnrollmentView
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private void факультетыToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormFaculties));
if (Service is FormFaculties Form)
{
Form.ShowDialog();
}
}
private void направленияToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormCourses));
if (Service is FormCourses Form)
{
Form.ShowDialog();
}
}
private void студентыToolStripMenuItem_Click(object sender, EventArgs e)
{
var Service = Program.ServiceProvider?.GetService(typeof(FormStudents));
if (Service is FormStudents Form)
{
Form.ShowDialog();
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(IFacultyLogic));
if (service is IFacultyLogic logic)
{
DateTime startTime = DateTime.Now;
for (int i = 0; i < 1000; i++)
{
logic.Create(new FacultyBindingModel
{
FacultyName = "факультет " + i,
});
}
DateTime endTime = DateTime.Now;
labelAdd.Text = $"{(endTime - startTime).TotalMilliseconds} мс";
}
}
private void buttonGet_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(IFacultyLogic));
if (service is IFacultyLogic logic)
{
DateTime startTime = DateTime.Now;
logic.ReadList(null);
DateTime endTime = DateTime.Now;
labelGet.Text = $"{(endTime - startTime).TotalMilliseconds} мс";
}
}
private void buttonUpdate_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(IFacultyLogic));
if (service is IFacultyLogic logic)
{
List<int> ids = logic.ReadList(null).Select(x => x.Id).ToList();
DateTime startTime = DateTime.Now;
for (int i = 0; i < ids.Count; i++)
{
logic.Update(new FacultyBindingModel
{
Id = ids[i],
FacultyName = "новый факультет " + i,
});
}
DateTime endTime = DateTime.Now;
labelUpdate.Text = $"{(endTime - startTime).TotalMilliseconds} мс";
}
}
private void buttonDelete_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(IFacultyLogic));
if (service is IFacultyLogic logic)
{
List<int> ids = logic.ReadList(null).Select(x => x.Id).ToList();
DateTime startTime = DateTime.Now;
for (int i = 0; i < ids.Count; i++)
{
logic.Delete(new FacultyBindingModel
{
Id = ids[i],
});
}
DateTime endTime = DateTime.Now;
labelDelete.Text = $"{(endTime - startTime).TotalMilliseconds} мс";
}
}
}
}

View File

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

View File

@ -0,0 +1,314 @@
namespace StudentEnrollmentView
{
partial class FormStudent
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
label2 = new Label();
textBoxLastName = new TextBox();
groupBox1 = new GroupBox();
buttonRef = new Button();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
ColumnId = new DataGridViewTextBoxColumn();
ColumnCourseName = new DataGridViewTextBoxColumn();
buttonCancel = new Button();
buttonSave = new Button();
label1 = new Label();
textBoxFirstName = new TextBox();
label3 = new Label();
textBoxMiddleName = new TextBox();
label4 = new Label();
textBoxEmail = new TextBox();
label5 = new Label();
textBoxTIN = new TextBox();
buttonAddPoints = new Button();
groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(19, 20);
label2.Name = "label2";
label2.Size = new Size(76, 20);
label2.TabIndex = 5;
label2.Text = "Фамилия:";
//
// textBoxLastName
//
textBoxLastName.Location = new Point(109, 16);
textBoxLastName.Margin = new Padding(3, 4, 3, 4);
textBoxLastName.Name = "textBoxLastName";
textBoxLastName.Size = new Size(285, 27);
textBoxLastName.TabIndex = 4;
//
// groupBox1
//
groupBox1.Controls.Add(buttonRef);
groupBox1.Controls.Add(buttonDel);
groupBox1.Controls.Add(buttonUpd);
groupBox1.Controls.Add(buttonAdd);
groupBox1.Controls.Add(dataGridView);
groupBox1.Location = new Point(420, 20);
groupBox1.Margin = new Padding(3, 4, 3, 4);
groupBox1.Name = "groupBox1";
groupBox1.Padding = new Padding(3, 4, 3, 4);
groupBox1.Size = new Size(341, 333);
groupBox1.TabIndex = 8;
groupBox1.TabStop = false;
groupBox1.Text = "Направление";
//
// buttonRef
//
buttonRef.Location = new Point(205, 176);
buttonRef.Margin = new Padding(3, 4, 3, 4);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(118, 37);
buttonRef.TabIndex = 8;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += buttonRef_Click;
//
// buttonDel
//
buttonDel.Location = new Point(205, 131);
buttonDel.Margin = new Padding(3, 4, 3, 4);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(118, 37);
buttonDel.TabIndex = 7;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += buttonDel_Click;
//
// buttonUpd
//
buttonUpd.Location = new Point(205, 86);
buttonUpd.Margin = new Padding(3, 4, 3, 4);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(118, 37);
buttonUpd.TabIndex = 6;
buttonUpd.Text = "Изменить";
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += buttonUpd_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(205, 40);
buttonAdd.Margin = new Padding(3, 4, 3, 4);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(118, 37);
buttonAdd.TabIndex = 5;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Columns.AddRange(new DataGridViewColumn[] { ColumnId, ColumnCourseName });
dataGridView.Location = new Point(7, 29);
dataGridView.Margin = new Padding(3, 4, 3, 4);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(180, 290);
dataGridView.TabIndex = 0;
//
// ColumnId
//
ColumnId.HeaderText = "ColumnId";
ColumnId.MinimumWidth = 6;
ColumnId.Name = "ColumnId";
ColumnId.Visible = false;
ColumnId.Width = 125;
//
// ColumnCourseName
//
ColumnCourseName.HeaderText = "Направление";
ColumnCourseName.MinimumWidth = 6;
ColumnCourseName.Name = "ColumnCourseName";
ColumnCourseName.Width = 125;
//
// buttonCancel
//
buttonCancel.Location = new Point(642, 368);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(119, 37);
buttonCancel.TabIndex = 10;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += buttonCancel_Click;
//
// buttonSave
//
buttonSave.Location = new Point(516, 368);
buttonSave.Margin = new Padding(3, 4, 3, 4);
buttonSave.Name = "buttonSave";
buttonSave.Size = new Size(119, 37);
buttonSave.TabIndex = 9;
buttonSave.Text = "Сохранить";
buttonSave.UseVisualStyleBackColor = true;
buttonSave.Click += buttonSave_Click;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(19, 63);
label1.Name = "label1";
label1.Size = new Size(42, 20);
label1.TabIndex = 12;
label1.Text = "Имя:";
//
// textBoxFirstName
//
textBoxFirstName.Location = new Point(109, 59);
textBoxFirstName.Margin = new Padding(3, 4, 3, 4);
textBoxFirstName.Name = "textBoxFirstName";
textBoxFirstName.Size = new Size(285, 27);
textBoxFirstName.TabIndex = 11;
//
// label3
//
label3.Location = new Point(16, 98);
label3.Name = "label3";
label3.Size = new Size(130, 44);
label3.TabIndex = 14;
label3.Text = "Отчество (при наличии):";
//
// textBoxMiddleName
//
textBoxMiddleName.Location = new Point(155, 106);
textBoxMiddleName.Margin = new Padding(3, 4, 3, 4);
textBoxMiddleName.Name = "textBoxMiddleName";
textBoxMiddleName.Size = new Size(239, 27);
textBoxMiddleName.TabIndex = 13;
//
// label4
//
label4.AutoSize = true;
label4.Location = new Point(19, 159);
label4.Name = "label4";
label4.Size = new Size(54, 20);
label4.TabIndex = 16;
label4.Text = "Почта:";
//
// textBoxEmail
//
textBoxEmail.Location = new Point(109, 155);
textBoxEmail.Margin = new Padding(3, 4, 3, 4);
textBoxEmail.Name = "textBoxEmail";
textBoxEmail.Size = new Size(285, 27);
textBoxEmail.TabIndex = 15;
//
// label5
//
label5.AutoSize = true;
label5.Location = new Point(19, 213);
label5.Name = "label5";
label5.Size = new Size(45, 20);
label5.TabIndex = 18;
label5.Text = "ИНН:";
//
// textBoxTIN
//
textBoxTIN.Location = new Point(109, 209);
textBoxTIN.Margin = new Padding(3, 4, 3, 4);
textBoxTIN.Name = "textBoxTIN";
textBoxTIN.Size = new Size(285, 27);
textBoxTIN.TabIndex = 17;
//
// buttonAddPoints
//
buttonAddPoints.Location = new Point(19, 368);
buttonAddPoints.Margin = new Padding(3, 4, 3, 4);
buttonAddPoints.Name = "buttonAddPoints";
buttonAddPoints.Size = new Size(229, 37);
buttonAddPoints.TabIndex = 19;
buttonAddPoints.Text = "Добавить баллы студента";
buttonAddPoints.UseVisualStyleBackColor = true;
buttonAddPoints.Click += buttonAddPoints_Click;
//
// FormStudent
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(773, 418);
Controls.Add(buttonAddPoints);
Controls.Add(label5);
Controls.Add(textBoxTIN);
Controls.Add(label4);
Controls.Add(textBoxEmail);
Controls.Add(label3);
Controls.Add(textBoxMiddleName);
Controls.Add(label1);
Controls.Add(textBoxFirstName);
Controls.Add(buttonCancel);
Controls.Add(buttonSave);
Controls.Add(groupBox1);
Controls.Add(label2);
Controls.Add(textBoxLastName);
Margin = new Padding(3, 4, 3, 4);
Name = "FormStudent";
Text = "Студент";
Load += FormStudent_Load;
groupBox1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Label label2;
private TextBox textBoxLastName;
private GroupBox groupBox1;
private DataGridView dataGridView;
private Button buttonRef;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private Button buttonCancel;
private Button buttonSave;
private DataGridViewTextBoxColumn ColumnId;
private DataGridViewTextBoxColumn ColumnCourseName;
private Label label1;
private TextBox textBoxFirstName;
private Label label3;
private TextBox textBoxMiddleName;
private Label label4;
private TextBox textBoxEmail;
private Label label5;
private TextBox textBoxTIN;
private Button buttonAddPoints;
}
}

View File

@ -0,0 +1,239 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.SearchModels;
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentView
{
public partial class FormStudent : Form
{
private readonly ILogger _logger;
private readonly IStudentLogic _logic;
private readonly IExamPointsLogic _examPointsLogic;
private int? _id;
private Dictionary<int, ICourseModel> _studentCourses;
private IExamPointsModel _examPoints;
public int Id { set { _id = value; } }
public FormStudent(ILogger<FormStudent> logger, IStudentLogic logic, IExamPointsLogic examPointsLogic)
{
InitializeComponent();
dataGridView.AllowUserToAddRows = false;
_logger = logger;
_logic = logic;
_examPointsLogic = examPointsLogic;
_studentCourses = new Dictionary<int, ICourseModel>();
}
private void FormStudent_Load(object sender, EventArgs e)
{
if (_id.HasValue)
{
_logger.LogInformation("Загрузка студента");
try
{
var view = _logic.ReadElement(new StudentSearchModel
{
student_id = _id.Value
});
if (view != null)
{
textBoxLastName.Text = view.LastName;
textBoxFirstName.Text = view.FirstName;
textBoxMiddleName.Text = view.MiddleName;
textBoxEmail.Text = view.Email;
textBoxTIN.Text = view.TIN.ToString();
_studentCourses = view.StudentCourse ?? new Dictionary<int, ICourseModel>();
var test = _examPointsLogic.ReadElement(new ExamPointsSearchModel
{
exampoints_id = view.ExamPointsId,
});
_examPoints = test;
LoadData();
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки студента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void LoadData()
{
_logger.LogInformation("Загрузка направлений студента");
try
{
if (_studentCourses != null)
{
dataGridView.Rows.Clear();
foreach (var pc in _studentCourses)
{
dataGridView.Rows.Add(new object[] { pc.Key, pc.Value.name });
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки направлений студента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStudentCourse));
if (service is FormStudentCourse form)
{
if (form.ShowDialog() == DialogResult.OK)
{
if (form.CourseModel == null)
{
return;
}
_logger.LogInformation("Добавление нового направления:{ CourseName}", form.CourseModel.name);
if (_studentCourses.ContainsKey(form.Id))
{
_studentCourses[form.Id] = form.CourseModel;
}
else
{
_studentCourses.Add(form.Id, form.CourseModel);
}
LoadData();
}
}
}
private void buttonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStudentCourse));
if (service is FormStudentCourse form)
{
int id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value);
form.Id = id;
if (form.ShowDialog() == DialogResult.OK)
{
if (form.CourseModel == null)
{
return;
}
_logger.LogInformation("Изменение направления:{ CourseName }", form.CourseModel.name);
_studentCourses[form.Id] = form.CourseModel;
LoadData();
}
}
}
}
private void buttonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
_logger.LogInformation("Удаление направления:{ CourseName}", dataGridView.SelectedRows[0].Cells[1].Value);
_studentCourses?.Remove(Convert.ToInt32(dataGridView.SelectedRows[0].Cells[0].Value));
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
LoadData();
}
}
}
private void buttonRef_Click(object sender, EventArgs e)
{
LoadData();
}
private void buttonSave_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(textBoxFirstName.Text))
{
MessageBox.Show("Заполните имя", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxLastName.Text))
{
MessageBox.Show("Заполните фамилию", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxEmail.Text))
{
MessageBox.Show("Заполните почту", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (string.IsNullOrEmpty(textBoxTIN.Text))
{
MessageBox.Show("Заполните ИНН", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_studentCourses.Count == 0 || _studentCourses == null)
{
MessageBox.Show("Заполните направления", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
if (_examPoints == null
|| (_examPoints.FirstExamPoints == 0
&& _examPoints.SecondExamPoints == 0
&& _examPoints.ThirdExamPoints == 0))
{
MessageBox.Show("Заполните баллы студента", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
_logger.LogInformation("Сохранение студента");
try
{
var model = new StudentBindingModel
{
Id = _id ?? 0,
FirstName = textBoxFirstName.Text,
LastName = textBoxLastName.Text,
MiddleName = !string.IsNullOrEmpty(textBoxMiddleName.Text) ? textBoxMiddleName.Text : string.Empty,
Email = textBoxEmail.Text,
TIN = Convert.ToInt64(textBoxTIN.Text),
StudentCourse = _studentCourses,
ExamPointsId = _examPoints.Id,
};
var operationResult = _id.HasValue ? _logic.Update(model) : _logic.Create(model);
if (!operationResult)
{
throw new Exception("Ошибка при сохранении. Дополнительная информация в логах.");
}
MessageBox.Show("Сохранение прошло успешно", "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Information);
DialogResult = DialogResult.OK;
Close();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка сохранения студента");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void buttonAddPoints_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormExamPoints));
if (service is FormExamPoints form)
{
form.Id = _id ?? 0;
if (form.ShowDialog() == DialogResult.OK)
{
_examPoints = form.ExamPoints;
}
}
}
}
}

View File

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

View File

@ -0,0 +1,101 @@
namespace StudentEnrollmentView
{
partial class FormStudentCourse
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
comboBoxCourse = new ComboBox();
label1 = new Label();
buttonAdd = new Button();
buttonCancel = new Button();
SuspendLayout();
//
// comboBoxCourse
//
comboBoxCourse.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxCourse.FormattingEnabled = true;
comboBoxCourse.Location = new Point(154, 13);
comboBoxCourse.Margin = new Padding(3, 4, 3, 4);
comboBoxCourse.Name = "comboBoxCourse";
comboBoxCourse.Size = new Size(285, 28);
comboBoxCourse.TabIndex = 0;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(11, 16);
label1.Name = "label1";
label1.Size = new Size(107, 20);
label1.TabIndex = 2;
label1.Text = "Направление:";
//
// buttonAdd
//
buttonAdd.Location = new Point(215, 58);
buttonAdd.Margin = new Padding(3, 4, 3, 4);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(98, 31);
buttonAdd.TabIndex = 4;
buttonAdd.Text = "Сохранить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += ButtonSave_Click;
//
// buttonCancel
//
buttonCancel.Location = new Point(320, 58);
buttonCancel.Margin = new Padding(3, 4, 3, 4);
buttonCancel.Name = "buttonCancel";
buttonCancel.Size = new Size(98, 31);
buttonCancel.TabIndex = 5;
buttonCancel.Text = "Отмена";
buttonCancel.UseVisualStyleBackColor = true;
buttonCancel.Click += ButtonCancel_Click;
//
// FormStudentCourse
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(451, 108);
Controls.Add(buttonCancel);
Controls.Add(buttonAdd);
Controls.Add(label1);
Controls.Add(comboBoxCourse);
Margin = new Padding(3, 4, 3, 4);
Name = "FormStudentCourse";
Text = "Направление студента";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ComboBox comboBoxCourse;
private Label label1;
private Button buttonAdd;
private Button buttonCancel;
}
}

View File

@ -0,0 +1,67 @@
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.ViewModels;
using StudentEnrollmentDataModels.Models;
namespace StudentEnrollmentView
{
public partial class FormStudentCourse : Form
{
private readonly List<CourseViewModel>? _list;
public int Id
{
get
{
return Convert.ToInt32(comboBoxCourse.SelectedValue);
}
set
{
comboBoxCourse.SelectedValue = value;
}
}
public ICourseModel? CourseModel
{
get
{
if (_list == null)
{
return null;
}
foreach (var elem in _list)
{
if (elem.course_id == Id)
{
return elem;
}
}
return null;
}
}
public FormStudentCourse(ICourseLogic logic)
{
InitializeComponent();
_list = logic.ReadList(null);
if (_list != null)
{
comboBoxCourse.DisplayMember = "name";
comboBoxCourse.ValueMember = "course_id";
comboBoxCourse.DataSource = _list;
comboBoxCourse.SelectedItem = null;
}
}
private void ButtonSave_Click(object sender, EventArgs e)
{
if (comboBoxCourse.SelectedValue == null)
{
MessageBox.Show("Выберите направление", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
DialogResult = DialogResult.OK;
Close();
}
private void ButtonCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
}
}

View File

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

View File

@ -0,0 +1,120 @@
namespace StudentEnrollmentView
{
partial class FormStudents
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
buttonRef = new Button();
buttonDel = new Button();
buttonUpd = new Button();
buttonAdd = new Button();
dataGridView = new DataGridView();
((System.ComponentModel.ISupportInitialize)dataGridView).BeginInit();
SuspendLayout();
//
// buttonRef
//
buttonRef.Location = new Point(794, 164);
buttonRef.Margin = new Padding(3, 4, 3, 4);
buttonRef.Name = "buttonRef";
buttonRef.Size = new Size(118, 37);
buttonRef.TabIndex = 14;
buttonRef.Text = "Обновить";
buttonRef.UseVisualStyleBackColor = true;
buttonRef.Click += buttonRef_Click;
//
// buttonDel
//
buttonDel.Location = new Point(794, 119);
buttonDel.Margin = new Padding(3, 4, 3, 4);
buttonDel.Name = "buttonDel";
buttonDel.Size = new Size(118, 37);
buttonDel.TabIndex = 13;
buttonDel.Text = "Удалить";
buttonDel.UseVisualStyleBackColor = true;
buttonDel.Click += buttonDel_Click;
//
// buttonUpd
//
buttonUpd.Location = new Point(794, 73);
buttonUpd.Margin = new Padding(3, 4, 3, 4);
buttonUpd.Name = "buttonUpd";
buttonUpd.Size = new Size(118, 37);
buttonUpd.TabIndex = 12;
buttonUpd.Text = "Изменить";
buttonUpd.UseVisualStyleBackColor = true;
buttonUpd.Click += buttonUpd_Click;
//
// buttonAdd
//
buttonAdd.Location = new Point(794, 28);
buttonAdd.Margin = new Padding(3, 4, 3, 4);
buttonAdd.Name = "buttonAdd";
buttonAdd.Size = new Size(118, 37);
buttonAdd.TabIndex = 11;
buttonAdd.Text = "Добавить";
buttonAdd.UseVisualStyleBackColor = true;
buttonAdd.Click += buttonAdd_Click;
//
// dataGridView
//
dataGridView.BackgroundColor = Color.White;
dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView.Location = new Point(12, 13);
dataGridView.Margin = new Padding(3, 4, 3, 4);
dataGridView.Name = "dataGridView";
dataGridView.RowHeadersWidth = 51;
dataGridView.RowTemplate.Height = 25;
dataGridView.Size = new Size(747, 568);
dataGridView.TabIndex = 10;
//
// FormStudents
//
AutoScaleDimensions = new SizeF(8F, 20F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(934, 597);
Controls.Add(buttonRef);
Controls.Add(buttonDel);
Controls.Add(buttonUpd);
Controls.Add(buttonAdd);
Controls.Add(dataGridView);
Name = "FormStudents";
Text = "Студенты";
Load += FormStudents_Load;
((System.ComponentModel.ISupportInitialize)dataGridView).EndInit();
ResumeLayout(false);
}
#endregion
private Button buttonRef;
private Button buttonDel;
private Button buttonUpd;
private Button buttonAdd;
private DataGridView dataGridView;
}
}

View File

@ -0,0 +1,103 @@
using Microsoft.Extensions.Logging;
using StudentEnrollmentContracts.BindingModels;
using StudentEnrollmentContracts.BusinessLogicContracts;
namespace StudentEnrollmentView
{
public partial class FormStudents : Form
{
private readonly ILogger _logger;
private readonly IStudentLogic _logic;
public FormStudents(ILogger<FormStudents> logger, IStudentLogic logic)
{
InitializeComponent();
_logger = logger;
_logic = logic;
}
private void FormStudents_Load(object sender, EventArgs e)
{
LoadData();
}
private void LoadData()
{
try
{
var list = _logic.ReadList(null);
if (list != null)
{
dataGridView.DataSource = list;
dataGridView.Columns["Id"].Visible = false;
dataGridView.Columns["ExamPointsId"].Visible = false;
dataGridView.Columns["StudentCourse"].Visible = false;
}
_logger.LogInformation("Загрузка студентов");
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка загрузки студентов");
}
}
private void buttonAdd_Click(object sender, EventArgs e)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStudent));
if (service is FormStudent form)
{
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
private void buttonUpd_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
var service = Program.ServiceProvider?.GetService(typeof(FormStudent));
if (service is FormStudent form)
{
form.Id = Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
if (form.ShowDialog() == DialogResult.OK)
{
LoadData();
}
}
}
}
private void buttonDel_Click(object sender, EventArgs e)
{
if (dataGridView.SelectedRows.Count == 1)
{
if (MessageBox.Show("Удалить запись?", "Вопрос", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
int id =
Convert.ToInt32(dataGridView.SelectedRows[0].Cells["Id"].Value);
_logger.LogInformation("Удаление записи");
try
{
if (!_logic.Delete(new StudentBindingModel
{
Id = id
}))
{
throw new Exception("Ошибка при удалении. Дополнительная информация в логах.");
}
LoadData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Ошибка удаления записи");
MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void buttonRef_Click(object sender, EventArgs e)
{
LoadData();
}
}
}

View File

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

View File

@ -0,0 +1,57 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using StudentEnrollmentBusinessLogic;
using StudentEnrollmentContracts.BusinessLogicContracts;
using StudentEnrollmentContracts.StorageContracts;
using StudentEnrollmentDatabaseImplement.Implements;
namespace StudentEnrollmentView
{
internal static class Program
{
private static ServiceProvider? _serviceProvider;
public static ServiceProvider? ServiceProvider => _serviceProvider;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
Application.Run(_serviceProvider.GetRequiredService<FormMain>());
}
private static void ConfigureServices(ServiceCollection services)
{
services.AddLogging(option =>
{
option.SetMinimumLevel(LogLevel.Information);
option.AddNLog("nlog.config");
});
services.AddTransient<IFacultyStorage, FacultyStorage>();
services.AddTransient<ICourseStorage, CourseStorage>();
services.AddTransient<IStudentStorage, StudentStorage>();
services.AddTransient<IExamPointsStorage, ExamPointsStorage>();
services.AddTransient<IFacultyLogic, FacultyLogic>();
services.AddTransient<ICourseLogic, CourseLogic>();
services.AddTransient<IStudentLogic, StudentLogic>();
services.AddTransient<IExamPointsLogic, ExamPointsLogic>();
services.AddTransient<FormMain>();
services.AddTransient<FormStudent>();
services.AddTransient<FormStudents>();
services.AddTransient<FormStudentCourse>();
services.AddTransient<FormExamPoints>();
services.AddTransient<FormFaculties>();
services.AddTransient<FormFaculty>();
services.AddTransient<FormCourses>();
services.AddTransient<FormCourse>();
}
}
}

View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.18">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="NLog" Version="5.3.2" />
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.10" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\StudentEnrollmentBusinessLogic\StudentEnrollmentBusinessLogic.csproj" />
<ProjectReference Include="..\StudentEnrollmentContracts\StudentEnrollmentContracts.csproj" />
<ProjectReference Include="..\StudentEnrollmentDatabaseImplement\StudentEnrollmentDatabaseImplement.csproj" />
</ItemGroup>
</Project>