From 78c105f309492e815e6001acb85673b1a69693e2 Mon Sep 17 00:00:00 2001 From: esantangelo <enzo020895@gmail.com> Date: Mon, 30 Nov 2020 21:10:53 -0300 Subject: [PATCH] add grade entity --- .../Controllers/ActivityController.cs | 60 ++ Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs | 16 + .../Helpers/ErrorMessages.cs | 2 + .../Helpers/MappingProfile.cs | 2 + .../Interfaces/IActivityService.cs | 4 + .../Services/ActivityService.cs | 223 ++++- Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs | 3 + Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs | 21 + Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs | 3 + .../EntityConfiguration/GradeConfiguration.cs | 29 + ...0201130004426_add-grade-entity.Designer.cs | 941 ++++++++++++++++++ .../20201130004426_add-grade-entity.cs | 48 + .../Migrations/Tsi1ContextModelSnapshot.cs | 36 + Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs | 3 + 14 files changed, 1389 insertions(+), 2 deletions(-) create mode 100644 Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs create mode 100644 Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs create mode 100644 Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs create mode 100644 Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.Designer.cs create mode 100644 Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.cs diff --git a/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs index d859323..6987480 100644 --- a/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs +++ b/Tsi1.Api/Tsi1.Api/Controllers/ActivityController.cs @@ -80,5 +80,65 @@ namespace Tsi1.Api.Controllers return Ok(); } + + [Authorize(Roles = UserTypes.Professor)] + [HttpPut("AddOrModifyGrade")] + public async Task<IActionResult> AddOrModifyGrade(GradeDto gradeDto) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + var result = await _activityService.AddOrModifyGrade(gradeDto, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Professor)] + [HttpDelete("DeleteGrade/{activityId}/{userId}")] + public async Task<IActionResult> DeleteGrade(int activityId, int userId) + { + var myUserId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + var result = await _activityService.DeleteGrade(myUserId, activityId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(); + } + + [Authorize(Roles = UserTypes.Student)] + [HttpGet("GetMyGrades/{activityId}")] + public async Task<IActionResult> GetMyGrades(int activityId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + var result = await _activityService.GetMyGrades(activityId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } + + [Authorize(Roles = UserTypes.Professor + ", " + UserTypes.FacultyAdmin)] + [HttpGet("GetAllGrades/{activityId}")] + public async Task<IActionResult> GetAllGrades(int activityId) + { + var userId = int.Parse(HttpContext.User.Claims.FirstOrDefault(x => x.Type == "Id").Value); + var result = await _activityService.GetAllGrades(activityId, userId); + + if (result.HasError) + { + return BadRequest(result.Message); + } + + return Ok(result.Data); + } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs new file mode 100644 index 0000000..4876ec9 --- /dev/null +++ b/Tsi1.Api/Tsi1.BusinessLayer/Dtos/GradeDto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json.Serialization; + +namespace Tsi1.BusinessLayer.Dtos +{ + public class GradeDto + { + public int ActivityId { get; set; } + + public int UserId { get; set; } + + public decimal Value { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs index 14da5d5..2b12422 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/ErrorMessages.cs @@ -67,5 +67,7 @@ namespace Tsi1.BusinessLayer.Helpers public const string InvalidTenant = "El usuario no pertenece a la facultad con id '{0}'"; public const string ActivityDoesNotExist = "La actividad con id '{0}' no existe"; + + public const string GradeDoesNotExist = "La nota para la actividad con id '{0}' y usuario con id '{0}' no existe"; } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs index 8116ab9..f0da4ed 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Helpers/MappingProfile.cs @@ -57,6 +57,7 @@ namespace Tsi1.BusinessLayer.Helpers CreateMap<Activity, ActivityCreateDto>(); CreateMap<Activity, ActivityModifyDto>(); CreateMap<Activity, ActivityDto>(); + CreateMap<Grade, GradeDto>(); CreateMap<ForumCreateDto, Forum>(); CreateMap<ForumPreviewDto, Forum>(); @@ -103,6 +104,7 @@ namespace Tsi1.BusinessLayer.Helpers CreateMap<ActivityCreateDto, Activity>(); CreateMap<ActivityModifyDto, Activity>(); CreateMap<ActivityDto, Activity>(); + CreateMap<GradeDto, Grade>(); } } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs index 4b0e88a..2dafbb7 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Interfaces/IActivityService.cs @@ -16,5 +16,9 @@ namespace Tsi1.BusinessLayer.Interfaces Task<ServiceResult<int>> Delete(int activityId, int userId); Task<ServiceResult<int>> ActivityValidation(int activityId); + Task<ServiceResult<GradeDto>> AddOrModifyGrade(GradeDto gradeDto, int userId); + Task<ServiceResult<int>> DeleteGrade(int myUserId, int activityId, int userId); + Task<ServiceResult<List<GradeDto>>> GetMyGrades(int activityId, int userId); + Task<ServiceResult<List<GradeDto>>> GetAllGrades(int activityId, int userId); } } diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs index 9ab568e..706d49f 100644 --- a/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs +++ b/Tsi1.Api/Tsi1.BusinessLayer/Services/ActivityService.cs @@ -67,9 +67,9 @@ namespace Tsi1.BusinessLayer.Services return result; } - private async Task<ServiceResult<bool>> UserTypeValidation(int courseId, int userId) + private async Task<ServiceResult<User>> UserTypeValidation(int courseId, int userId) { - var result = new ServiceResult<bool>(); + var result = new ServiceResult<User>(); var user = await _context.Users.AsNoTracking() .Include(x => x.UserType) @@ -96,6 +96,21 @@ namespace Tsi1.BusinessLayer.Services } } + if (user.UserType.Name == UserTypes.Student) + { + var isStudentCourse = await _context.StudentCourses + .AsNoTracking() + .AnyAsync(x => x.StudentId == user.StudentId && x.CourseId == courseId); + + if (!isStudentCourse) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.StudentCourseDoesNotExists, user.Id, courseId)); + + } + } + + result.Data = user; return result; } @@ -223,5 +238,209 @@ namespace Tsi1.BusinessLayer.Services result.Data = activity.Id; return result; } + + public async Task<ServiceResult<GradeDto>> AddOrModifyGrade(GradeDto gradeDto, int userId) + { + var result = new ServiceResult<GradeDto>(); + + var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == gradeDto.ActivityId); + + if (activity == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, gradeDto.ActivityId)); + return result; + } + + var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); + + if (userTypeValidation.HasError) + { + result.HasError = true; + result.AddMessage(userTypeValidation.Message); + return result; + } + + var userStudent = await _context.Users + .Include(x => x.Student) + .FirstOrDefaultAsync(x => x.Id == gradeDto.UserId); + + if (userStudent == null || userStudent.Student == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.StudentDoesNotExist, gradeDto.UserId)); + return result; + } + + var userStudentValidation = await this.UserTypeValidation(activity.CourseId, userStudent.Id); + + if (userStudentValidation.HasError) + { + result.HasError = true; + result.AddMessage(userStudentValidation.Message); + return result; + } + + var grade = await _context.Grades + .FirstOrDefaultAsync(x => x.ActivityId == gradeDto.ActivityId && x.StudentId == userStudent.StudentId); + + if (grade == null) + { + grade = new Grade + { + ActivityId = gradeDto.ActivityId, + StudentId = (int)userStudent.StudentId + }; + + _context.Grades.Add(grade); + } + + grade.Value = gradeDto.Value; + + + await _context.SaveChangesAsync(); + + result.Data = gradeDto; + return result; + } + + public async Task<ServiceResult<int>> DeleteGrade(int myUserId, int activityId, int userId) + { + var result = new ServiceResult<int>(); + + var userStudent = await _context.Users + .AsNoTracking() + .Include(x => x.Student) + .FirstOrDefaultAsync(x => x.Id == userId); + + if (userStudent == null || userStudent.Student == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.StudentDoesNotExist, userStudent.Id)); + return result; + } + + var grade = await _context.Grades + .FirstOrDefaultAsync(x => x.ActivityId == activityId && x.StudentId == userStudent.StudentId); + + if (grade == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.GradeDoesNotExist, activityId, userId)); + return result; + } + + var activity = await _context.Activities.FirstOrDefaultAsync(x => x.Id == activityId); + + if (activity == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); + return result; + } + + var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); + + if (userTypeValidation.HasError) + { + result.HasError = true; + result.AddMessage(userTypeValidation.Message); + return result; + } + + _context.Grades.Remove(grade); + await _context.SaveChangesAsync(); + + return result; + } + + public async Task<ServiceResult<List<GradeDto>>> GetMyGrades(int activityId, int userId) + { + var result = new ServiceResult<List<GradeDto>>(); + + var activity = await _context.Activities.AsNoTracking().FirstOrDefaultAsync(x => x.Id == activityId); + + if (activity == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); + return result; + } + + var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); + + if (userTypeValidation.HasError) + { + result.HasError = true; + result.AddMessage(userTypeValidation.Message); + return result; + } + + var user = userTypeValidation.Data; + + var grades = await _context.Grades + .AsNoTracking() + .Where(x => x.ActivityId == activityId && x.StudentId == user.StudentId) + .ToListAsync(); + + result.Data = _mapper.Map<List<GradeDto>>(grades); + return result; + } + + public async Task<ServiceResult<List<GradeDto>>> GetAllGrades(int activityId, int userId) + { + var result = new ServiceResult<List<GradeDto>>(); + + var activity = await _context.Activities.AsNoTracking().FirstOrDefaultAsync(x => x.Id == activityId); + + if (activity == null) + { + result.HasError = true; + result.AddMessage(string.Format(ErrorMessages.ActivityDoesNotExist, activityId)); + return result; + } + + var userTypeValidation = await this.UserTypeValidation(activity.CourseId, userId); + + if (userTypeValidation.HasError) + { + result.HasError = true; + result.AddMessage(userTypeValidation.Message); + return result; + } + + var user = userTypeValidation.Data; + + var grades = await _context.Grades + .AsNoTracking() + .Where(x => x.ActivityId == activityId) + .ToListAsync(); + + var studentIds = grades.Select(x => x.StudentId).ToList(); + + var users = await _context.Users + .AsNoTracking() + .Where(x => studentIds.Contains((int)x.StudentId)) + .ToListAsync(); + + var gradeDtos = new List<GradeDto>(); + + foreach (var grade in grades) + { + var userStudent = users.FirstOrDefault(x => x.StudentId == grade.StudentId); + + var gradeDto = new GradeDto + { + ActivityId = grade.ActivityId, + UserId = userStudent.Id, + Value = grade.Value + }; + + gradeDtos.Add(gradeDto); + } + + result.Data = gradeDtos; + return result; + } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs index 4a0ad03..ca3a040 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Activity.cs @@ -9,6 +9,7 @@ namespace Tsi1.DataLayer.Entities public Activity() { Attendances = new HashSet<Attendance>(); + Grades = new HashSet<Grade>(); } public int Id { get; set; } @@ -22,5 +23,7 @@ namespace Tsi1.DataLayer.Entities public Course Course { get; set; } public ICollection<Attendance> Attendances { get; set; } + + public ICollection<Grade> Grades { get; set; } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs new file mode 100644 index 0000000..c5c05e7 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Grade.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Tsi1.DataLayer.Entities +{ + public class Grade + { + public int ActivityId { get; set; } + + public int StudentId { get; set; } + + public decimal Value { get; set; } + + public DateTime Date { get; set; } + + public Student Student { get; set; } + + public Activity Activity { get; set; } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs index 2688e37..866c516 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs @@ -9,6 +9,7 @@ namespace Tsi1.DataLayer.Entities public Student() { StudentCourses = new HashSet<StudentCourse>(); + Grades = new HashSet<Grade>(); } public int Id { get; set; } @@ -22,5 +23,7 @@ namespace Tsi1.DataLayer.Entities public Tenant Tenant { get; set; } public User User { get; set; } public ICollection<StudentCourse> StudentCourses { get; set; } + + public ICollection<Grade> Grades { get; set; } } } diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs new file mode 100644 index 0000000..d8596a9 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/GradeConfiguration.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using System; +using System.Collections.Generic; +using System.Text; +using Tsi1.DataLayer.Entities; + +namespace Tsi1.DataLayer.EntityConfiguration +{ + public class GradeConfiguration : IEntityTypeConfiguration<Grade> + { + public void Configure(EntityTypeBuilder<Grade> builder) + { + builder.HasKey(x => new { x.ActivityId, x.StudentId}); + + builder.Property(x => x.Value) + .IsRequired() + .HasColumnType("NUMERIC(5,2)"); + + builder.HasOne(x => x.Activity) + .WithMany(x => x.Grades) + .HasForeignKey(x => x.ActivityId); + + builder.HasOne(x => x.Student) + .WithMany(x => x.Grades) + .HasForeignKey(x => x.StudentId); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.Designer.cs new file mode 100644 index 0000000..5c64c37 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.Designer.cs @@ -0,0 +1,941 @@ +// <auto-generated /> +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using Tsi1.DataLayer; + +namespace Tsi1.DataLayer.Migrations +{ + [DbContext(typeof(Tsi1Context))] + [Migration("20201130004426_add-grade-entity")] + partial class addgradeentity + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<bool>("IsVideoConference") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Activities"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.AnswerOption", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AnswerOptions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ActivityId"); + + b.HasIndex("UserId"); + + b.ToTable("Attendances"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("CourseId") + .HasColumnType("integer"); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.Property<string>("Text") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.Property<DateTime>("ValidUntil") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.HasIndex("TenantId"); + + b.HasIndex("ValidUntil"); + + b.ToTable("Communications"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.Property<string>("ConnectionId") + .HasColumnType("text"); + + b.Property<string>("GroupName") + .HasColumnType("text"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ConnectionId"); + + b.HasIndex("GroupName"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsTemplate") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("Name", "TenantId") + .IsUnique(); + + b.ToTable("Courses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.File", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<string>("Path") + .IsRequired() + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Forum", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Forums"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("ForumId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ForumUsers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<decimal>("Value") + .HasColumnType("NUMERIC(5,2)"); + + b.HasKey("ActivityId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("Grades"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b => + { + b.Property<string>("Name") + .HasColumnType("text"); + + b.HasKey("Name"); + + b.ToTable("Groups"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("ForumId") + .HasColumnType("integer"); + + b.Property<string>("Title") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.HasIndex("ForumId", "Title") + .IsUnique(); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Content") + .IsRequired() + .HasColumnType("character varying(10485760)"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<int>("PostId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostMessages"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Professors"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.Property<int>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("ProfessorId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("ProfessorCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CourseId"); + + b.ToTable("Sections"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int?>("FileId") + .HasColumnType("integer"); + + b.Property<int?>("ForumId") + .HasColumnType("integer"); + + b.Property<int>("Order") + .HasColumnType("integer"); + + b.Property<int>("SectionId") + .HasColumnType("integer"); + + b.Property<int>("SectionItemTypeId") + .HasColumnType("integer"); + + b.Property<int?>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("FileId") + .IsUnique(); + + b.HasIndex("ForumId") + .IsUnique(); + + b.HasIndex("SectionId"); + + b.HasIndex("SectionItemTypeId"); + + b.HasIndex("SurveyId") + .IsUnique(); + + b.ToTable("SectionItems"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItemType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("SectionItemTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("Age") + .HasColumnType("integer"); + + b.Property<string>("IdentityCard") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TenantId"); + + b.HasIndex("IdentityCard", "TenantId") + .IsUnique(); + + b.ToTable("Students"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("CourseId") + .HasColumnType("integer"); + + b.HasKey("StudentId", "CourseId"); + + b.HasIndex("CourseId"); + + b.ToTable("StudentCourses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<bool>("IsGlobal") + .HasColumnType("boolean"); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("TenantId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.HasIndex("TenantId"); + + b.ToTable("Surveys"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("AnswerOptionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyQuestionId") + .HasColumnType("integer"); + + b.Property<int>("SurveyResponseId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AnswerOptionId"); + + b.HasIndex("SurveyQuestionId"); + + b.HasIndex("SurveyResponseId"); + + b.ToTable("SurveyAnswers"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Question") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.ToTable("SurveyQuestions"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<int>("SurveyId") + .HasColumnType("integer"); + + b.Property<int>("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("SurveyId"); + + b.HasIndex("UserId"); + + b.ToTable("SurveyResponses"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Tenant", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Email") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("FirstName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("LastName") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<string>("Password") + .IsRequired() + .HasColumnType("character varying(255)"); + + b.Property<int?>("ProfessorId") + .HasColumnType("integer"); + + b.Property<int?>("StudentId") + .HasColumnType("integer"); + + b.Property<int>("TenantId") + .HasColumnType("integer"); + + b.Property<int>("UserTypeId") + .HasColumnType("integer"); + + b.Property<string>("Username") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ProfessorId") + .IsUnique(); + + b.HasIndex("StudentId") + .IsUnique(); + + b.HasIndex("TenantId"); + + b.HasIndex("UserTypeId"); + + b.HasIndex("Username", "TenantId") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.UserType", b => + { + b.Property<int>("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property<string>("Name") + .IsRequired() + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("UserTypes"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Activity", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Activities") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Attendance", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Attendances") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Attendances") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Communication", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Communications") + .HasForeignKey("CourseId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Communications") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Connection", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Group", "Group") + .WithMany("Connections") + .HasForeignKey("GroupName"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Course", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Courses") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ForumUser", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("ForumUsers") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("ForumUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Grades") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Grades") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithMany("Posts") + .HasForeignKey("ForumId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("Posts") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.PostMessage", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Post", "Post") + .WithMany("PostMessages") + .HasForeignKey("PostId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("PostMessages") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Professor", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Professors") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.ProfessorCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("ProfessorCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithMany("ProfessorCourses") + .HasForeignKey("ProfessorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Section", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("Sections") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SectionItem", b => + { + b.HasOne("Tsi1.DataLayer.Entities.File", "File") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "FileId"); + + b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "ForumId"); + + b.HasOne("Tsi1.DataLayer.Entities.Section", "Section") + .WithMany("SectionItems") + .HasForeignKey("SectionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SectionItemType", "SectionItemType") + .WithMany("SectionItems") + .HasForeignKey("SectionItemTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithOne("SectionItem") + .HasForeignKey("Tsi1.DataLayer.Entities.SectionItem", "SurveyId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Student", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Students") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.StudentCourse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Course", "Course") + .WithMany("StudentCourses") + .HasForeignKey("CourseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("StudentCourses") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.Survey", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Surveys") + .HasForeignKey("TenantId"); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyAnswer", b => + { + b.HasOne("Tsi1.DataLayer.Entities.AnswerOption", "AnswerOption") + .WithMany("SurveyAnswers") + .HasForeignKey("AnswerOptionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyQuestion", "SurveyQuestion") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyQuestionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.SurveyResponse", "SurveyResponse") + .WithMany("SurveyAnswers") + .HasForeignKey("SurveyResponseId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyQuestion", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyQuestions") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.SurveyResponse", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Survey", "Survey") + .WithMany("SurveyResponses") + .HasForeignKey("SurveyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.User", "User") + .WithMany("SurveyResponses") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tsi1.DataLayer.Entities.User", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Professor", "Professor") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "ProfessorId"); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithOne("User") + .HasForeignKey("Tsi1.DataLayer.Entities.User", "StudentId"); + + b.HasOne("Tsi1.DataLayer.Entities.Tenant", "Tenant") + .WithMany("Users") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.UserType", "UserType") + .WithMany() + .HasForeignKey("UserTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.cs new file mode 100644 index 0000000..8dd5eb3 --- /dev/null +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201130004426_add-grade-entity.cs @@ -0,0 +1,48 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tsi1.DataLayer.Migrations +{ + public partial class addgradeentity : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Grades", + columns: table => new + { + ActivityId = table.Column<int>(nullable: false), + StudentId = table.Column<int>(nullable: false), + Value = table.Column<decimal>(type: "NUMERIC(5,2)", nullable: false), + Date = table.Column<DateTime>(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Grades", x => new { x.ActivityId, x.StudentId }); + table.ForeignKey( + name: "FK_Grades_Activities_ActivityId", + column: x => x.ActivityId, + principalTable: "Activities", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Grades_Students_StudentId", + column: x => x.StudentId, + principalTable: "Students", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Grades_StudentId", + table: "Grades", + column: "StudentId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Grades"); + } + } +} diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs index 08b6205..c7ee2e5 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs @@ -219,6 +219,27 @@ namespace Tsi1.DataLayer.Migrations b.ToTable("ForumUsers"); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.Property<int>("ActivityId") + .HasColumnType("integer"); + + b.Property<int>("StudentId") + .HasColumnType("integer"); + + b.Property<DateTime>("Date") + .HasColumnType("timestamp without time zone"); + + b.Property<decimal>("Value") + .HasColumnType("NUMERIC(5,2)"); + + b.HasKey("ActivityId", "StudentId"); + + b.HasIndex("StudentId"); + + b.ToTable("Grades"); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Group", b => { b.Property<string>("Name") @@ -709,6 +730,21 @@ namespace Tsi1.DataLayer.Migrations .IsRequired(); }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Grade", b => + { + b.HasOne("Tsi1.DataLayer.Entities.Activity", "Activity") + .WithMany("Grades") + .HasForeignKey("ActivityId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tsi1.DataLayer.Entities.Student", "Student") + .WithMany("Grades") + .HasForeignKey("StudentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Tsi1.DataLayer.Entities.Post", b => { b.HasOne("Tsi1.DataLayer.Entities.Forum", "Forum") diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs index bda60bb..e99928e 100644 --- a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs +++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs @@ -36,6 +36,8 @@ namespace Tsi1.DataLayer public DbSet<Activity> Activities { get; set; } public DbSet<Attendance> Attendances { get; set; } + public DbSet<Grade> Grades { get; set; } + public Tsi1Context(DbContextOptions options) : base(options) { } @@ -68,6 +70,7 @@ namespace Tsi1.DataLayer modelBuilder.ApplyConfiguration(new CommunicationConfiguration()); modelBuilder.ApplyConfiguration(new ActivityConfiguration()); modelBuilder.ApplyConfiguration(new AttendanceConfiguration()); + modelBuilder.ApplyConfiguration(new GradeConfiguration()); } } } -- GitLab