diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a4e3726 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea/ +.vs/ +[Bb]in/ +[Oo]bj/ \ No newline at end of file diff --git a/Presence.API/Controllers/GroupController.cs b/Presence.API/Controllers/GroupController.cs new file mode 100644 index 0000000..5272d88 --- /dev/null +++ b/Presence.API/Controllers/GroupController.cs @@ -0,0 +1,49 @@ +using domain.Request; +using domain.UseCase; +using Microsoft.AspNetCore.Mvc; +using Presence.API.Response; + +namespace Presence.API.Controllers +{ + [ApiController] + [Route("api/[controller]")] + public class GroupController : ControllerBase + { + private readonly IGroupUseCase _groupService; + + public GroupController(IGroupUseCase groupService) + { + _groupService = groupService; + } + + [HttpGet("/group")] + public ActionResult GetAllGroups() + { + var result = _groupService + .GetGroupsWithStudents() + .Select(group => new GroupResponse + { + Id = group.Id, + Name = group.Name, + Users = group.Users?.Select( + user => new UserResponse + { + Id = user.Id, + LastName = user.LastName, + FirstName = user.FirstName, + Patronymic = user.Patronymic + }).ToList() + }).ToList(); + return Ok(result); + } + + [HttpDelete("/group/{id}")] + public IActionResult DeleteGroup(int id) + { + RemoveGroupRequest removeGroupRequest = new() { GroupId = id }; + _groupService.RemoveGroup(removeGroupRequest); + return NoContent(); + } + + } +} diff --git a/Presence.API/Extensions/ServiceCollectionExtension.cs b/Presence.API/Extensions/ServiceCollectionExtension.cs new file mode 100644 index 0000000..890ad9f --- /dev/null +++ b/Presence.API/Extensions/ServiceCollectionExtension.cs @@ -0,0 +1,20 @@ +using data; +using data.Repository; +using domain.Service; +using domain.UseCase; +using Presence.API.Controllers; + +namespace Presence.API.Extensions +{ + public static class ServiceCollectionExtension + { + public static void AddCommonServices(this IServiceCollection services) + { + services + .AddDbContext() + .AddScoped() + .AddScoped() + .AddScoped(); + } + } +} diff --git a/Presence.API/Presence.API.csproj b/Presence.API/Presence.API.csproj new file mode 100644 index 0000000..01b9d0e --- /dev/null +++ b/Presence.API/Presence.API.csproj @@ -0,0 +1,22 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + diff --git a/Presence.API/Presence.API.csproj.user b/Presence.API/Presence.API.csproj.user new file mode 100644 index 0000000..9ff5820 --- /dev/null +++ b/Presence.API/Presence.API.csproj.user @@ -0,0 +1,6 @@ + + + + https + + \ No newline at end of file diff --git a/Presence.API/Presence.API.http b/Presence.API/Presence.API.http new file mode 100644 index 0000000..290e1f2 --- /dev/null +++ b/Presence.API/Presence.API.http @@ -0,0 +1,6 @@ +@Presence.API_HostAddress = http://localhost:5275 + +GET {{Presence.API_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/Presence.API/Program.cs b/Presence.API/Program.cs new file mode 100644 index 0000000..a3de2b8 --- /dev/null +++ b/Presence.API/Program.cs @@ -0,0 +1,38 @@ + +using Presence.API.Extensions; + +namespace Presence.API +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + builder.Services.AddCommonServices(); + builder.Services.AddControllers(); + // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle + builder.Services.AddEndpointsApiExplorer(); + builder.Services.AddSwaggerGen(); + + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + if (app.Environment.IsDevelopment()) + { + app.UseSwagger(); + app.UseSwaggerUI(); + } + + app.UseHttpsRedirection(); + + app.UseAuthorization(); + + app.MapControllers(); + + app.Run(); + } + } +} diff --git a/Presence.API/Properties/launchSettings.json b/Presence.API/Properties/launchSettings.json new file mode 100644 index 0000000..7727652 --- /dev/null +++ b/Presence.API/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:56416", + "sslPort": 44345 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7226;http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Presence.API/Response/GroupResponse.cs b/Presence.API/Response/GroupResponse.cs new file mode 100644 index 0000000..28982da --- /dev/null +++ b/Presence.API/Response/GroupResponse.cs @@ -0,0 +1,10 @@ +namespace Presence.API.Response +{ + public class GroupResponse + { + public int Id { get; set; } + public string Name { get; set; } + + public IEnumerable? Users { get; set; } = null; + } +} diff --git a/Presence.API/Response/UserResponse.cs b/Presence.API/Response/UserResponse.cs new file mode 100644 index 0000000..97c4a49 --- /dev/null +++ b/Presence.API/Response/UserResponse.cs @@ -0,0 +1,13 @@ +namespace Presence.API.Response +{ + public class UserResponse + { + public int Id { get; set; } + + public string LastName { get; set; } + + public string FirstName { get; set; } + + public string Patronymic { get; set; } + } +} diff --git a/Presence.API/appsettings.Development.json b/Presence.API/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Presence.API/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Presence.API/appsettings.json b/Presence.API/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Presence.API/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/console_ui/Program.cs b/console_ui/Program.cs new file mode 100644 index 0000000..d24ffa7 --- /dev/null +++ b/console_ui/Program.cs @@ -0,0 +1,36 @@ +using console_ui.UI; +using data; +using data.Repository; +using domain.Service; +using domain.UseCase; +using Microsoft.Extensions.DependencyInjection; + +namespace console_ui +{ + class Program + { + static void Main(string[] args) + { + IServiceCollection services = new ServiceCollection(); + services + .AddDbContext() + .AddSingleton() + .AddSingleton() + .AddSingleton(); + + var serviceProvider = services.BuildServiceProvider(); + var groupUI = serviceProvider.GetService(); + var repo = serviceProvider.GetService(); + + printAllGroups(repo!); + } + + static void printAllGroups(IGroupRepository groupRepository) + { + foreach (var item in groupRepository.GetAllGroups()) + { + Console.WriteLine($"{item.Id} \t {item.Name}"); + } + } + } +} diff --git a/console_ui/UI/GroupUI.cs b/console_ui/UI/GroupUI.cs new file mode 100644 index 0000000..0a7c07b --- /dev/null +++ b/console_ui/UI/GroupUI.cs @@ -0,0 +1,54 @@ +using domain.Request; +using domain.Service; +using domain.UseCase; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace console_ui.UI +{ + public class GroupUI + { + private readonly IGroupUseCase _groupService; + + public GroupUI(IGroupUseCase groupService) + { + _groupService = groupService; + } + + public void AddGroup() + { + Console.Write("Введите имя группы: "); + _groupService.AddGroup(new AddGroupRequest { Name = Console.ReadLine() }); + } + + public void AddGroupWithStudents() + { + Console.Write("Введите имя группы: "); + AddGroupRequest addGroupRequest = new AddGroupRequest { Name = Console.ReadLine() }; + List addStudentRequests = new List() + { + new AddStudentRequest {FirstName = "Имя", LastName = "Фамилия", Patronymic = "Отчество"}, + new AddStudentRequest {FirstName = "Imya", LastName = "Familiya", Patronymic = "Otchestvo"}, + new AddStudentRequest {FirstName = "FirstName", LastName = "LastName", Patronymic = "Patronymic"}, + new AddStudentRequest {FirstName = "1", LastName = "2", Patronymic = "3"}, + }; + AddGroupWithStudentRequest addGroupWithStudentRequest = new() + { + AddGroupRequest = addGroupRequest, + AddStudentRequests = addStudentRequests + }; + + _groupService.AddGroupWithStudents(addGroupWithStudentRequest); + } + + public void RemoveGroup() + { + Console.Write("Введите индетефикатор группы: "); + RemoveGroupRequest removeGroupRequest = new RemoveGroupRequest { GroupId = int.Parse(Console.ReadLine()) }; + _groupService.RemoveGroup(removeGroupRequest); + } + } +} diff --git a/console_ui/console_ui.csproj b/console_ui/console_ui.csproj new file mode 100644 index 0000000..5d0e73d --- /dev/null +++ b/console_ui/console_ui.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/data/DAO/Diary.cs b/data/DAO/Diary.cs new file mode 100644 index 0000000..d2269ba --- /dev/null +++ b/data/DAO/Diary.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + public class Diary + { + [Key] + public int Id { get; set; } + + public string DiaryText { get; set; } + + public int TrafficId { get; set; } + + public int StudentGroupSubjectId { get; set; } + + public virtual Traffic Traffic { get; set; } + + public virtual StudentGroupSubject StudentGroupSubject { get; set; } + public virtual Student Student { get; set; } + + public int NumberSubject { get; set; } + + public DateOnly Date { get; set; } + } +} diff --git a/data/DAO/Group.cs b/data/DAO/Group.cs new file mode 100644 index 0000000..e9fcb81 --- /dev/null +++ b/data/DAO/Group.cs @@ -0,0 +1,19 @@ + +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + public class Group + { + [Key] + public int Id { get; set; } + public string Name { get; set; } + + public virtual ICollection Students { get; set; } = new List(); + } +} diff --git a/data/DAO/Student.cs b/data/DAO/Student.cs new file mode 100644 index 0000000..3150df5 --- /dev/null +++ b/data/DAO/Student.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + public class Student + { + [Key] + public int Id { get; set; } + + public string LastName { get; set; } + + public string FirstName { get; set; } + + public string Patronymic { get; set; } + + public int GroupId { get; set; } + + public virtual Group Group { get; set; } + } +} diff --git a/data/DAO/StudentGroupSubject.cs b/data/DAO/StudentGroupSubject.cs new file mode 100644 index 0000000..4908547 --- /dev/null +++ b/data/DAO/StudentGroupSubject.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + public class StudentGroupSubject + { + [Key] + public int Id { get; set; } + public virtual Group Group { get; set; } + public int SemesterStart { get; set; } + public int SemesterEnd { get; set; } + public virtual Subject Subject { get; set; } + } +} diff --git a/data/DAO/Subject.cs b/data/DAO/Subject.cs new file mode 100644 index 0000000..2c5e547 --- /dev/null +++ b/data/DAO/Subject.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + // Предметы + public class Subject + { + [Key] + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/data/DAO/Traffic.cs b/data/DAO/Traffic.cs new file mode 100644 index 0000000..4e37168 --- /dev/null +++ b/data/DAO/Traffic.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.DAO +{ + public class Traffic + { + [Key] + public int Id { get; set; } + public string Name { get; set; } + } +} diff --git a/data/DatabaseContext.cs b/data/DatabaseContext.cs new file mode 100644 index 0000000..7078d1a --- /dev/null +++ b/data/DatabaseContext.cs @@ -0,0 +1,47 @@ +using data.DAO; +using Microsoft.EntityFrameworkCore; + +namespace data; + +public class DatabaseContext : DbContext +{ + public DatabaseContext() { } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseNpgsql("Host=45.67.56.214;Port=5454;Username=user13;Password=keNBA0yK"); + + public DbSet Students { get; set; } + + public DbSet Groups { get; set; } + + public DbSet Diaries { get; set; } + + public DbSet Subjects { get; set; } + + public DbSet Traffics { get; set; } + + public DbSet StudentGroupsSubjects { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + modelBuilder.Entity().Property(it => it.Id).ValueGeneratedOnAdd(); + + modelBuilder.Entity() + .HasOne(it => it.Group); + modelBuilder.Entity() + .HasOne(it => it.StudentGroupSubject); + modelBuilder.Entity() + .HasOne(it => it.Traffic); + modelBuilder.Entity() + .HasOne(it => it.Student); + modelBuilder.Entity() + .HasOne(it => it.Group); + modelBuilder.Entity() + .HasOne(it => it.Subject); + } +} diff --git a/data/Migrations/20241120062915_InitialCreate.Designer.cs b/data/Migrations/20241120062915_InitialCreate.Designer.cs new file mode 100644 index 0000000..0cf9a46 --- /dev/null +++ b/data/Migrations/20241120062915_InitialCreate.Designer.cs @@ -0,0 +1,222 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using data; + +#nullable disable + +namespace data.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241120062915_InitialCreate")] + partial class InitialCreate + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DiaryText") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberSubject") + .HasColumnType("integer"); + + b.Property("StudentGroupSubjectId") + .HasColumnType("integer"); + + b.Property("TrafficId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("StudentGroupSubjectId"); + + b.HasIndex("TrafficId"); + + b.ToTable("Diaries"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("SemesterEnd") + .HasColumnType("integer"); + + b.Property("SemesterStart") + .HasColumnType("integer"); + + b.Property("SubjectId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("SubjectId"); + + b.ToTable("StudentGroupsSubjects"); + }); + + modelBuilder.Entity("data.DAO.Subject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Subjects"); + }); + + modelBuilder.Entity("data.DAO.Traffic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Traffics"); + }); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.HasOne("data.DAO.StudentGroupSubject", "StudentGroupSubject") + .WithMany() + .HasForeignKey("StudentGroupSubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Traffic", "Traffic") + .WithMany() + .HasForeignKey("TrafficId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("StudentGroupSubject"); + + b.Navigation("Traffic"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Subject", "Subject") + .WithMany() + .HasForeignKey("SubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Subject"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/data/Migrations/20241120062915_InitialCreate.cs b/data/Migrations/20241120062915_InitialCreate.cs new file mode 100644 index 0000000..2e7dd2d --- /dev/null +++ b/data/Migrations/20241120062915_InitialCreate.cs @@ -0,0 +1,181 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace data.Migrations +{ + /// + public partial class InitialCreate : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Groups", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Groups", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Subjects", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Subjects", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Traffics", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Traffics", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Students", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + LastName = table.Column(type: "text", nullable: false), + FirstName = table.Column(type: "text", nullable: false), + Patronymic = table.Column(type: "text", nullable: false), + GroupId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Students", x => x.Id); + table.ForeignKey( + name: "FK_Students_Groups_GroupId", + column: x => x.GroupId, + principalTable: "Groups", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "StudentGroupsSubjects", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + GroupId = table.Column(type: "integer", nullable: false), + SemesterStart = table.Column(type: "integer", nullable: false), + SemesterEnd = table.Column(type: "integer", nullable: false), + SubjectId = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_StudentGroupsSubjects", x => x.Id); + table.ForeignKey( + name: "FK_StudentGroupsSubjects_Groups_GroupId", + column: x => x.GroupId, + principalTable: "Groups", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_StudentGroupsSubjects_Subjects_SubjectId", + column: x => x.SubjectId, + principalTable: "Subjects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Diaries", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + DiaryText = table.Column(type: "text", nullable: false), + TrafficId = table.Column(type: "integer", nullable: false), + StudentGroupSubjectId = table.Column(type: "integer", nullable: false), + NumberSubject = table.Column(type: "integer", nullable: false), + Date = table.Column(type: "date", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Diaries", x => x.Id); + table.ForeignKey( + name: "FK_Diaries_StudentGroupsSubjects_StudentGroupSubjectId", + column: x => x.StudentGroupSubjectId, + principalTable: "StudentGroupsSubjects", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Diaries_Traffics_TrafficId", + column: x => x.TrafficId, + principalTable: "Traffics", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Diaries_StudentGroupSubjectId", + table: "Diaries", + column: "StudentGroupSubjectId"); + + migrationBuilder.CreateIndex( + name: "IX_Diaries_TrafficId", + table: "Diaries", + column: "TrafficId"); + + migrationBuilder.CreateIndex( + name: "IX_StudentGroupsSubjects_GroupId", + table: "StudentGroupsSubjects", + column: "GroupId"); + + migrationBuilder.CreateIndex( + name: "IX_StudentGroupsSubjects_SubjectId", + table: "StudentGroupsSubjects", + column: "SubjectId"); + + migrationBuilder.CreateIndex( + name: "IX_Students_GroupId", + table: "Students", + column: "GroupId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Diaries"); + + migrationBuilder.DropTable( + name: "Students"); + + migrationBuilder.DropTable( + name: "StudentGroupsSubjects"); + + migrationBuilder.DropTable( + name: "Traffics"); + + migrationBuilder.DropTable( + name: "Groups"); + + migrationBuilder.DropTable( + name: "Subjects"); + } + } +} diff --git a/data/Migrations/20241122130535_Fix.Designer.cs b/data/Migrations/20241122130535_Fix.Designer.cs new file mode 100644 index 0000000..96ca4f2 --- /dev/null +++ b/data/Migrations/20241122130535_Fix.Designer.cs @@ -0,0 +1,240 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using data; + +#nullable disable + +namespace data.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241122130535_Fix")] + partial class Fix + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DiaryText") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberSubject") + .HasColumnType("integer"); + + b.Property("StudentGroupSubjectId") + .HasColumnType("integer"); + + b.Property("TrafficId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("StudentGroupSubjectId"); + + b.HasIndex("TrafficId"); + + b.ToTable("Diaries"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("SemesterEnd") + .HasColumnType("integer"); + + b.Property("SemesterStart") + .HasColumnType("integer"); + + b.Property("StudentId") + .HasColumnType("integer"); + + b.Property("SubjectId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("StudentId"); + + b.HasIndex("SubjectId"); + + b.ToTable("StudentGroupsSubjects"); + }); + + modelBuilder.Entity("data.DAO.Subject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Subjects"); + }); + + modelBuilder.Entity("data.DAO.Traffic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Traffics"); + }); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.HasOne("data.DAO.StudentGroupSubject", "StudentGroupSubject") + .WithMany() + .HasForeignKey("StudentGroupSubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Traffic", "Traffic") + .WithMany() + .HasForeignKey("TrafficId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("StudentGroupSubject"); + + b.Navigation("Traffic"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany("Students") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Subject", "Subject") + .WithMany() + .HasForeignKey("SubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Student"); + + b.Navigation("Subject"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Navigation("Students"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/data/Migrations/20241122130535_Fix.cs b/data/Migrations/20241122130535_Fix.cs new file mode 100644 index 0000000..211a4ce --- /dev/null +++ b/data/Migrations/20241122130535_Fix.cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace data.Migrations +{ + /// + public partial class Fix : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "StudentId", + table: "StudentGroupsSubjects", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_StudentGroupsSubjects_StudentId", + table: "StudentGroupsSubjects", + column: "StudentId"); + + migrationBuilder.AddForeignKey( + name: "FK_StudentGroupsSubjects_Students_StudentId", + table: "StudentGroupsSubjects", + column: "StudentId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_StudentGroupsSubjects_Students_StudentId", + table: "StudentGroupsSubjects"); + + migrationBuilder.DropIndex( + name: "IX_StudentGroupsSubjects_StudentId", + table: "StudentGroupsSubjects"); + + migrationBuilder.DropColumn( + name: "StudentId", + table: "StudentGroupsSubjects"); + } + } +} diff --git a/data/Migrations/20241122130744_FixIssueAgain.Designer.cs b/data/Migrations/20241122130744_FixIssueAgain.Designer.cs new file mode 100644 index 0000000..74c01a5 --- /dev/null +++ b/data/Migrations/20241122130744_FixIssueAgain.Designer.cs @@ -0,0 +1,240 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using data; + +#nullable disable + +namespace data.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20241122130744_FixIssueAgain")] + partial class FixIssueAgain + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DiaryText") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberSubject") + .HasColumnType("integer"); + + b.Property("StudentGroupSubjectId") + .HasColumnType("integer"); + + b.Property("StudentId") + .HasColumnType("integer"); + + b.Property("TrafficId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("StudentGroupSubjectId"); + + b.HasIndex("StudentId"); + + b.HasIndex("TrafficId"); + + b.ToTable("Diaries"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("SemesterEnd") + .HasColumnType("integer"); + + b.Property("SemesterStart") + .HasColumnType("integer"); + + b.Property("SubjectId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("SubjectId"); + + b.ToTable("StudentGroupsSubjects"); + }); + + modelBuilder.Entity("data.DAO.Subject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Subjects"); + }); + + modelBuilder.Entity("data.DAO.Traffic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Traffics"); + }); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.HasOne("data.DAO.StudentGroupSubject", "StudentGroupSubject") + .WithMany() + .HasForeignKey("StudentGroupSubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Traffic", "Traffic") + .WithMany() + .HasForeignKey("TrafficId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Student"); + + b.Navigation("StudentGroupSubject"); + + b.Navigation("Traffic"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany("Students") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Subject", "Subject") + .WithMany() + .HasForeignKey("SubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Subject"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Navigation("Students"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/data/Migrations/20241122130744_FixIssueAgain.cs b/data/Migrations/20241122130744_FixIssueAgain.cs new file mode 100644 index 0000000..3412baa --- /dev/null +++ b/data/Migrations/20241122130744_FixIssueAgain.cs @@ -0,0 +1,82 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace data.Migrations +{ + /// + public partial class FixIssueAgain : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_StudentGroupsSubjects_Students_StudentId", + table: "StudentGroupsSubjects"); + + migrationBuilder.DropIndex( + name: "IX_StudentGroupsSubjects_StudentId", + table: "StudentGroupsSubjects"); + + migrationBuilder.DropColumn( + name: "StudentId", + table: "StudentGroupsSubjects"); + + migrationBuilder.AddColumn( + name: "StudentId", + table: "Diaries", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_Diaries_StudentId", + table: "Diaries", + column: "StudentId"); + + migrationBuilder.AddForeignKey( + name: "FK_Diaries_Students_StudentId", + table: "Diaries", + column: "StudentId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Diaries_Students_StudentId", + table: "Diaries"); + + migrationBuilder.DropIndex( + name: "IX_Diaries_StudentId", + table: "Diaries"); + + migrationBuilder.DropColumn( + name: "StudentId", + table: "Diaries"); + + migrationBuilder.AddColumn( + name: "StudentId", + table: "StudentGroupsSubjects", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateIndex( + name: "IX_StudentGroupsSubjects_StudentId", + table: "StudentGroupsSubjects", + column: "StudentId"); + + migrationBuilder.AddForeignKey( + name: "FK_StudentGroupsSubjects_Students_StudentId", + table: "StudentGroupsSubjects", + column: "StudentId", + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/data/Migrations/DatabaseContextModelSnapshot.cs b/data/Migrations/DatabaseContextModelSnapshot.cs new file mode 100644 index 0000000..8f2bbc7 --- /dev/null +++ b/data/Migrations/DatabaseContextModelSnapshot.cs @@ -0,0 +1,237 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using data; + +#nullable disable + +namespace data.Migrations +{ + [DbContext(typeof(DatabaseContext))] + partial class DatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("date"); + + b.Property("DiaryText") + .IsRequired() + .HasColumnType("text"); + + b.Property("NumberSubject") + .HasColumnType("integer"); + + b.Property("StudentGroupSubjectId") + .HasColumnType("integer"); + + b.Property("StudentId") + .HasColumnType("integer"); + + b.Property("TrafficId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("StudentGroupSubjectId"); + + b.HasIndex("StudentId"); + + b.HasIndex("TrafficId"); + + b.ToTable("Diaries"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("text"); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Patronymic") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("GroupId") + .HasColumnType("integer"); + + b.Property("SemesterEnd") + .HasColumnType("integer"); + + b.Property("SemesterStart") + .HasColumnType("integer"); + + b.Property("SubjectId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GroupId"); + + b.HasIndex("SubjectId"); + + b.ToTable("StudentGroupsSubjects"); + }); + + modelBuilder.Entity("data.DAO.Subject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Subjects"); + }); + + modelBuilder.Entity("data.DAO.Traffic", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Traffics"); + }); + + modelBuilder.Entity("data.DAO.Diary", b => + { + b.HasOne("data.DAO.StudentGroupSubject", "StudentGroupSubject") + .WithMany() + .HasForeignKey("StudentGroupSubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Student", "Student") + .WithMany() + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Traffic", "Traffic") + .WithMany() + .HasForeignKey("TrafficId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Student"); + + b.Navigation("StudentGroupSubject"); + + b.Navigation("Traffic"); + }); + + modelBuilder.Entity("data.DAO.Student", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany("Students") + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + }); + + modelBuilder.Entity("data.DAO.StudentGroupSubject", b => + { + b.HasOne("data.DAO.Group", "Group") + .WithMany() + .HasForeignKey("GroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("data.DAO.Subject", "Subject") + .WithMany() + .HasForeignKey("SubjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Group"); + + b.Navigation("Subject"); + }); + + modelBuilder.Entity("data.DAO.Group", b => + { + b.Navigation("Students"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/data/Repository/IGroupRepository.cs b/data/Repository/IGroupRepository.cs new file mode 100644 index 0000000..58945af --- /dev/null +++ b/data/Repository/IGroupRepository.cs @@ -0,0 +1,43 @@ +using data.DAO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace data.Repository +{ + public interface IGroupRepository + { + /// + /// Получение списка групп + /// + public IEnumerable GetAllGroups(); + + /// + /// Создание группы + /// + /// группа + public bool CreateGroup(Group group); + + /// + /// Создание группы вместо со студентами + /// + /// группа + /// список студентов + public bool AddGroupWithStudents(Group group, IEnumerable students); + + /// + /// Удаление группы по индетефикатору + /// + /// индетефикатор + public bool DeleteGroup(int id); + + /// + /// Обновление наименование группы + /// + /// индетефикатор + /// наименованвие + public bool UpdateGroup(int id, string name); + } +} diff --git a/data/Repository/SQLGroupRepository.cs b/data/Repository/SQLGroupRepository.cs new file mode 100644 index 0000000..49fbc94 --- /dev/null +++ b/data/Repository/SQLGroupRepository.cs @@ -0,0 +1,67 @@ +using data.DAO; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; + +namespace data.Repository +{ + public class SQLGroupRepository : IGroupRepository + { + private readonly DatabaseContext _dbContext; + public SQLGroupRepository(DatabaseContext dbContext) + { + _dbContext = dbContext; + } + + public bool AddGroupWithStudents(Group group, IEnumerable students) + { + using var transaction = _dbContext.Database.BeginTransaction(); + try + { + _dbContext.Groups.Add(group); + _dbContext.SaveChanges(); + foreach (var item in students) + { + item.Group = group; + _dbContext.Students.Add(item); + } + _dbContext.SaveChanges(); + transaction.Commit(); + return true; + } + catch (Exception ex) + { + Debug.WriteLine("Во время добавления группы со студентами произошла ошибка: ", ex.Message); + transaction.Rollback(); + } + return false; + } + + public bool CreateGroup(Group group) + { + _dbContext.Groups.Add(group); + return _dbContext.SaveChanges() > 0; + } + + public bool DeleteGroup(int id) + { + Group group = _dbContext.Groups.Single(g => g.Id == id); + _dbContext.Groups.Remove(group); + return _dbContext.SaveChanges() > 0; + } + + public IEnumerable GetAllGroups() + => _dbContext.Groups.Include(g => g.Students).ToList(); + + public bool UpdateGroup(int id, string name) + { + Group group = _dbContext.Groups.Single(g => g.Id == id); + group.Name = name; + return _dbContext.SaveChanges() > 0; + } + } +} diff --git a/data/data.csproj b/data/data.csproj new file mode 100644 index 0000000..dc73827 --- /dev/null +++ b/data/data.csproj @@ -0,0 +1,18 @@ + + + + net8.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + diff --git a/domain/Class1.cs b/domain/Class1.cs new file mode 100644 index 0000000..855623e --- /dev/null +++ b/domain/Class1.cs @@ -0,0 +1,7 @@ +namespace domain +{ + public class Class1 + { + + } +} diff --git a/domain/Entity/GroupEntity.cs b/domain/Entity/GroupEntity.cs new file mode 100644 index 0000000..5d11391 --- /dev/null +++ b/domain/Entity/GroupEntity.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Entity +{ + public class GroupEntity + { + public int Id { get; set; } + public string Name { get; set; } + public IEnumerable Users { get; set; } + } +} diff --git a/domain/Entity/UserEntity.cs b/domain/Entity/UserEntity.cs new file mode 100644 index 0000000..b48f78b --- /dev/null +++ b/domain/Entity/UserEntity.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Entity +{ + public class UserEntity + { + public int Id { get; set; } + + public string LastName { get; set; } + + public string FirstName { get; set; } + + public string Patronymic { get; set; } + public GroupEntity Group { get; set; } + } +} diff --git a/domain/Request/AddGroupRequest.cs b/domain/Request/AddGroupRequest.cs new file mode 100644 index 0000000..2f47fb8 --- /dev/null +++ b/domain/Request/AddGroupRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Request +{ + public class AddGroupRequest + { + public string Name { get; set; } + } +} diff --git a/domain/Request/AddGroupWithStudentRequest.cs b/domain/Request/AddGroupWithStudentRequest.cs new file mode 100644 index 0000000..1f3f02a --- /dev/null +++ b/domain/Request/AddGroupWithStudentRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Request +{ + public class AddGroupWithStudentRequest + { + public AddGroupRequest AddGroupRequest { get; set; } + public IEnumerable AddStudentRequests { get; set; } + } +} diff --git a/domain/Request/AddStudentRequest.cs b/domain/Request/AddStudentRequest.cs new file mode 100644 index 0000000..1274428 --- /dev/null +++ b/domain/Request/AddStudentRequest.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Request +{ + public class AddStudentRequest + { + public string LastName { get; set; } + + public string FirstName { get; set; } + + public string Patronymic { get; set; } + } +} diff --git a/domain/Request/EditGroupRequest.cs b/domain/Request/EditGroupRequest.cs new file mode 100644 index 0000000..fe5d9d1 --- /dev/null +++ b/domain/Request/EditGroupRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Request +{ + public class EditGroupRequest + { + public int GroupId { get; set; } + public string GroupName { get; set; } + } +} diff --git a/domain/Request/RemoveGroupRequest.cs b/domain/Request/RemoveGroupRequest.cs new file mode 100644 index 0000000..996a42d --- /dev/null +++ b/domain/Request/RemoveGroupRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Request +{ + public class RemoveGroupRequest + { + public int GroupId { get; set; } + } +} diff --git a/domain/Service/GroupService.cs b/domain/Service/GroupService.cs new file mode 100644 index 0000000..507fb28 --- /dev/null +++ b/domain/Service/GroupService.cs @@ -0,0 +1,66 @@ +using data.DAO; +using data.Repository; +using domain.Entity; +using domain.Request; +using domain.UseCase; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.Service +{ + public class GroupService : IGroupUseCase + { + private readonly IGroupRepository _groupRepository; + public GroupService(IGroupRepository groupRepository) + { + _groupRepository = groupRepository; + } + + public void AddGroup(AddGroupRequest addGroupRequest) + => _groupRepository.CreateGroup(new Group { Name = addGroupRequest.Name }); + + + public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudentRequest) + { + Group group = new Group { Name = addGroupWithStudentRequest.AddGroupRequest.Name }; + List students = addGroupWithStudentRequest + .AddStudentRequests + .Select(it => new Student { FirstName = it.FirstName, LastName = it.LastName, Patronymic = it.Patronymic}) + .ToList(); + + _groupRepository.AddGroupWithStudents(group, students); + } + + public void EditGroup(EditGroupRequest editGroupRequest) + => _groupRepository.UpdateGroup(editGroupRequest.GroupId, editGroupRequest.GroupName); + + public IEnumerable GetGroupsWithStudents() + { + return _groupRepository.GetAllGroups().Select( + group => new GroupEntity + { + Id = group.Id, + Name = group.Name, + Users = group.Students.Select( + user => new UserEntity + { + Id = user.Id, + LastName = user.LastName, + FirstName = user.FirstName, + Patronymic = user.Patronymic, + Group = new GroupEntity + { + Id = group.Id, + Name = group.Name + } + }) + }); + } + + public void RemoveGroup(RemoveGroupRequest removeGroupRequest) + => _groupRepository.DeleteGroup(removeGroupRequest.GroupId); + } +} diff --git a/domain/UseCase/IGroupUseCase.cs b/domain/UseCase/IGroupUseCase.cs new file mode 100644 index 0000000..3dd452f --- /dev/null +++ b/domain/UseCase/IGroupUseCase.cs @@ -0,0 +1,23 @@ +using domain.Entity; +using domain.Request; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace domain.UseCase +{ + public interface IGroupUseCase + { + public void AddGroup(AddGroupRequest addGroupRequest); + + public void AddGroupWithStudents(AddGroupWithStudentRequest addGroupWithStudentRequest); + + public void RemoveGroup(RemoveGroupRequest removeGroupRequest); + + public void EditGroup(EditGroupRequest editGroupRequest); + + public IEnumerable GetGroupsWithStudents(); + } +} diff --git a/domain/domain.csproj b/domain/domain.csproj new file mode 100644 index 0000000..f2296ed --- /dev/null +++ b/domain/domain.csproj @@ -0,0 +1,17 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + diff --git a/presence.sln b/presence.sln new file mode 100644 index 0000000..10e1507 --- /dev/null +++ b/presence.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "data", "data\data.csproj", "{BB350D5F-DE0B-465C-909F-6A179AA03C3A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "console_ui", "console_ui\console_ui.csproj", "{BD6F5F76-9186-4301-8506-EB78220FA095}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "domain", "domain\domain.csproj", "{4D39120E-C021-4D38-BB4D-2F58BDE5FE17}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Presence.API", "Presence.API\Presence.API.csproj", "{88AE15FA-7E2D-4D7C-A75B-7DAC9742B32A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB350D5F-DE0B-465C-909F-6A179AA03C3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB350D5F-DE0B-465C-909F-6A179AA03C3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB350D5F-DE0B-465C-909F-6A179AA03C3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB350D5F-DE0B-465C-909F-6A179AA03C3A}.Release|Any CPU.Build.0 = Release|Any CPU + {BD6F5F76-9186-4301-8506-EB78220FA095}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BD6F5F76-9186-4301-8506-EB78220FA095}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BD6F5F76-9186-4301-8506-EB78220FA095}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BD6F5F76-9186-4301-8506-EB78220FA095}.Release|Any CPU.Build.0 = Release|Any CPU + {4D39120E-C021-4D38-BB4D-2F58BDE5FE17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D39120E-C021-4D38-BB4D-2F58BDE5FE17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D39120E-C021-4D38-BB4D-2F58BDE5FE17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D39120E-C021-4D38-BB4D-2F58BDE5FE17}.Release|Any CPU.Build.0 = Release|Any CPU + {88AE15FA-7E2D-4D7C-A75B-7DAC9742B32A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {88AE15FA-7E2D-4D7C-A75B-7DAC9742B32A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {88AE15FA-7E2D-4D7C-A75B-7DAC9742B32A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {88AE15FA-7E2D-4D7C-A75B-7DAC9742B32A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D71F226C-A42E-49C2-9E51-10BE305FFC48} + EndGlobalSection +EndGlobal