diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..a9183b55b68a71ca47809af2e9361e03903aae0c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+################################################################################
+# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
+################################################################################
+
+.vs
+obj
+bin
diff --git a/Tsi1.Api/Tsi1.Api.sln b/Tsi1.Api/Tsi1.Api.sln
new file mode 100644
index 0000000000000000000000000000000000000000..d8cbb37464d1f64b8116052f7e82c4b19753afd3
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api.sln
@@ -0,0 +1,37 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30523.141
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.Api", "Tsi1.Api\Tsi1.Api.csproj", "{02E63197-0AEA-4942-941F-DFB7AD145A1E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.BusinessLayer", "Tsi1.BusinessLayer\Tsi1.BusinessLayer.csproj", "{3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tsi1.DataLayer", "Tsi1.DataLayer\Tsi1.DataLayer.csproj", "{57C4932A-C228-4A49-8FAC-8E9447F0E6E0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {02E63197-0AEA-4942-941F-DFB7AD145A1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {02E63197-0AEA-4942-941F-DFB7AD145A1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {02E63197-0AEA-4942-941F-DFB7AD145A1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {02E63197-0AEA-4942-941F-DFB7AD145A1E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B46AFDD-AB4A-4D0E-8A94-49559E1D2083}.Release|Any CPU.Build.0 = Release|Any CPU
+ {57C4932A-C228-4A49-8FAC-8E9447F0E6E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {57C4932A-C228-4A49-8FAC-8E9447F0E6E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {57C4932A-C228-4A49-8FAC-8E9447F0E6E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {57C4932A-C228-4A49-8FAC-8E9447F0E6E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {24FE2874-2ABA-4BEF-ADBF-7A14EF0BF03D}
+ EndGlobalSection
+EndGlobal
diff --git a/Tsi1.Api/Tsi1.Api/Program.cs b/Tsi1.Api/Tsi1.Api/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..50e6716c5925665dc0b091548bd2fc4b82d4b82c
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Program.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Tsi1.Api
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup<Startup>();
+ });
+ }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Properties/launchSettings.json b/Tsi1.Api/Tsi1.Api/Properties/launchSettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..24cce69c764987715a6740867b6857e7b9dbd4df
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Properties/launchSettings.json
@@ -0,0 +1,30 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:56409",
+ "sslPort": 44363
+ }
+ },
+ "profiles": {
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "weatherforecast",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "Tsi1.Api": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "weatherforecast",
+ "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Startup.cs b/Tsi1.Api/Tsi1.Api/Startup.cs
new file mode 100644
index 0000000000000000000000000000000000000000..6d3605800e6f7dccf3e2bd7f1d6ce5a882fec727
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Startup.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.HttpsPolicy;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Tsi1.DataLayer;
+
+namespace Tsi1.Api
+{
+ public class Startup
+ {
+ public Startup(IConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public IConfiguration Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddControllers();
+
+ services.AddDbContext<Tsi1Context>(x => x.UseNpgsql(Configuration.GetConnectionString("PostgreSql")));
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseHttpsRedirection();
+
+ app.UseRouting();
+
+ app.UseAuthorization();
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.Api/Tsi1.Api.csproj b/Tsi1.Api/Tsi1.Api/Tsi1.Api.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..cf8609719d70846dff5b7571b899da73861f6312
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/Tsi1.Api.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <Folder Include="Controllers\" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tsi1.BusinessLayer\Tsi1.BusinessLayer.csproj" />
+ </ItemGroup>
+
+
+</Project>
diff --git a/Tsi1.Api/Tsi1.Api/appsettings.Development.json b/Tsi1.Api/Tsi1.Api/appsettings.Development.json
new file mode 100644
index 0000000000000000000000000000000000000000..8983e0fc1c5e2795ccfde0c771c6d66c88ef4a42
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.Api/appsettings.json b/Tsi1.Api/Tsi1.Api/appsettings.json
new file mode 100644
index 0000000000000000000000000000000000000000..c796235b460965778236fabc90cdff4ede6f8d33
--- /dev/null
+++ b/Tsi1.Api/Tsi1.Api/appsettings.json
@@ -0,0 +1,13 @@
+{
+ "ConnectionStrings": {
+ "PostgreSql": "Host=localhost;Database=tsi1;Username=postgres;Password=111111"
+ },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/Tsi1.Api/Tsi1.BusinessLayer/Tsi1.BusinessLayer.csproj b/Tsi1.Api/Tsi1.BusinessLayer/Tsi1.BusinessLayer.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..71bca384a32afadf9f0d5acbb9ad681f05bc0cfa
--- /dev/null
+++ b/Tsi1.Api/Tsi1.BusinessLayer/Tsi1.BusinessLayer.csproj
@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tsi1.DataLayer\Tsi1.DataLayer.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/Tsi1.Api/Tsi1.DataLayer/DesignTimeDbContextFactory.cs b/Tsi1.Api/Tsi1.DataLayer/DesignTimeDbContextFactory.cs
new file mode 100644
index 0000000000000000000000000000000000000000..e83b49e66bbca9c750753fdae2d54c4970f757ee
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/DesignTimeDbContextFactory.cs
@@ -0,0 +1,27 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Design;
+using Microsoft.Extensions.Configuration;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Tsi1.DataLayer
+{
+ public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<Tsi1Context>
+ {
+ public Tsi1Context CreateDbContext(string[] args)
+ {
+ IConfigurationRoot configuration = new ConfigurationBuilder()
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile(@Directory.GetCurrentDirectory() + "/../Tsi1.Api/appsettings.json")
+ .Build();
+
+ var builder = new DbContextOptionsBuilder<Tsi1Context>();
+ var connectionString = configuration.GetConnectionString("PostgreSql");
+ builder.UseNpgsql(connectionString);
+
+ return new Tsi1Context(builder.Options);
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c884a8829e830ad5a51d858d4da3300288d039cf
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Course.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class Course
+ {
+ public Course()
+ {
+ StudentCourses = new HashSet<StudentCourse>();
+ ProfessorCourses = new HashSet<ProfessorCourse>();
+ }
+
+ public int Id { get; set; }
+ public string Name { get; set; }
+
+ public ICollection<StudentCourse> StudentCourses { get; set; }
+ public ICollection<ProfessorCourse> ProfessorCourses { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b72802f9d1ba2255ea1492228b4645f72797784e
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Professor.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class Professor
+ {
+ public Professor()
+ {
+ ProfessorCourses = new HashSet<ProfessorCourse>();
+ }
+
+ public int Id { get; set; }
+ public int UserId { get; set; }
+ public string IdentityCard { get; set; }
+
+ public User User { get; set; }
+ public ICollection<ProfessorCourse> ProfessorCourses { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/ProfessorCourse.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/ProfessorCourse.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7e6027715dd319d4c15d1d167336c496d77ada64
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/ProfessorCourse.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class ProfessorCourse
+ {
+ public int ProfessorId { get; set; }
+ public int CourseId { get; set; }
+
+ public Professor Professor { get; set; }
+ public Course Course { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs
new file mode 100644
index 0000000000000000000000000000000000000000..bf168e33d74bc58bedbcc7c74fdd01bce40dc053
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/Student.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class Student
+ {
+ public Student()
+ {
+ StudentCourses = new HashSet<StudentCourse>();
+ }
+
+ public int Id { get; set; }
+ public int UserId { get; set; }
+ public string IdentityCard { get; set; }
+ public int Age { get; set; }
+
+ public User User { get; set; }
+ public ICollection<StudentCourse> StudentCourses { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/StudentCourse.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/StudentCourse.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4a40e4199893659af7a628a64bbd6fe0e972b46a
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/StudentCourse.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class StudentCourse
+ {
+ public int StudentId { get; set; }
+ public int CourseId { get; set; }
+
+ public Student Student { get; set; }
+ public Course Course { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs
new file mode 100644
index 0000000000000000000000000000000000000000..637f94585126ec278d5f377993df55565e53e72c
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/User.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class User
+ {
+ public int Id { get; set; }
+ public int UserTypeId { get; set; }
+ public int? StudentId { get; set; }
+ public int? ProfessorId { get; set; }
+ public string Username { get; set; }
+ public string Password { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string Email { get; set; }
+
+ public UserType UserType { get; set; }
+ public Student Student { get; set; }
+ public Professor Professor { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Entities/UserType.cs b/Tsi1.Api/Tsi1.DataLayer/Entities/UserType.cs
new file mode 100644
index 0000000000000000000000000000000000000000..c06364f1adfa52b097c893ece3b0a0fa699a09a3
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Entities/UserType.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Tsi1.DataLayer.Entities
+{
+ public class UserType
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/CourseConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/CourseConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2bec81eac60a7426e67afd8bba3392d9cf17c89c
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/CourseConfiguration.cs
@@ -0,0 +1,24 @@
+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 CourseConfiguration : IEntityTypeConfiguration<Course>
+ {
+ public void Configure(EntityTypeBuilder<Course> builder)
+ {
+ builder.HasKey(x => x.Id);
+
+ builder.HasIndex(x => x.Name)
+ .IsUnique();
+
+ builder.Property(x => x.Name)
+ .IsRequired()
+ .HasColumnType("character varying(50)");
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..679dae301ad59a3b95baaf17c70661b3926f00b9
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorConfiguration.cs
@@ -0,0 +1,24 @@
+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 ProfessorConfiguration : IEntityTypeConfiguration<Professor>
+ {
+ public void Configure(EntityTypeBuilder<Professor> builder)
+ {
+ builder.HasKey(x => x.Id);
+
+ builder.HasIndex(x => x.IdentityCard)
+ .IsUnique();
+
+ builder.Property(x => x.IdentityCard)
+ .IsRequired()
+ .HasColumnType("character varying(50)");
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorCourseConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorCourseConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..8ed62457e8688b098835ee1bcb535a0040e23ca5
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/ProfessorCourseConfiguration.cs
@@ -0,0 +1,25 @@
+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 ProfessorCourseConfiguration : IEntityTypeConfiguration<ProfessorCourse>
+ {
+ public void Configure(EntityTypeBuilder<ProfessorCourse> builder)
+ {
+ builder.HasKey(x => new { x.ProfessorId, x.CourseId });
+
+ builder.HasOne(x => x.Course)
+ .WithMany(x => x.ProfessorCourses)
+ .HasForeignKey(x => x.CourseId);
+
+ builder.HasOne(x => x.Professor)
+ .WithMany(x => x.ProfessorCourses)
+ .HasForeignKey(x => x.ProfessorId);
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..a7877ace1f806e899748ba2d436186b7dad33de4
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentConfiguration.cs
@@ -0,0 +1,27 @@
+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 StudentConfiguration : IEntityTypeConfiguration<Student>
+ {
+ public void Configure(EntityTypeBuilder<Student> builder)
+ {
+ builder.HasKey(x => x.Id);
+
+ builder.HasIndex(x => x.IdentityCard)
+ .IsUnique();
+
+ builder.Property(x => x.IdentityCard)
+ .IsRequired()
+ .HasColumnType("character varying(50)");
+
+ builder.Property(x => x.Age)
+ .IsRequired();
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentCourseConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentCourseConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9c152ff81e54f95189d5657594adbf91bc797e4d
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/StudentCourseConfiguration.cs
@@ -0,0 +1,25 @@
+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 StudentCourseConfiguration : IEntityTypeConfiguration<StudentCourse>
+ {
+ public void Configure(EntityTypeBuilder<StudentCourse> builder)
+ {
+ builder.HasKey(x => new { x.StudentId, x.CourseId });
+
+ builder.HasOne(x => x.Course)
+ .WithMany(x => x.StudentCourses)
+ .HasForeignKey(x => x.CourseId);
+
+ builder.HasOne(x => x.Student)
+ .WithMany(x => x.StudentCourses)
+ .HasForeignKey(x => x.StudentId);
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..eadf441d032c10cc45e2b2552d386af604262e26
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserConfiguration.cs
@@ -0,0 +1,48 @@
+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 UserConfiguration : IEntityTypeConfiguration<User>
+ {
+ public void Configure(EntityTypeBuilder<User> builder)
+ {
+ builder.HasKey(x => x.Id);
+
+ builder.HasIndex(x => x.Username)
+ .IsUnique();
+
+ builder.Property(x => x.Username)
+ .IsRequired()
+ .HasColumnType("character varying(50)");
+
+ builder.Property(x => x.Password)
+ .IsRequired()
+ .HasColumnType("character varying(255)");
+
+ builder.Property(x => x.FirstName)
+ .IsRequired()
+ .HasColumnType("character varying(255)");
+
+ builder.Property(x => x.LastName)
+ .IsRequired()
+ .HasColumnType("character varying(255)");
+
+ builder.Property(x => x.Email)
+ .IsRequired()
+ .HasColumnType("character varying(255)");
+
+ builder.HasOne(x => x.Student)
+ .WithOne(x => x.User)
+ .HasForeignKey<User>(x => x.StudentId);
+
+ builder.HasOne(x => x.Professor)
+ .WithOne(x => x.User)
+ .HasForeignKey<User>(x => x.ProfessorId);
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserTypeConfiguration.cs b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserTypeConfiguration.cs
new file mode 100644
index 0000000000000000000000000000000000000000..2eacf371c34d67b647f266332493b34e9fcdaadd
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/EntityConfiguration/UserTypeConfiguration.cs
@@ -0,0 +1,24 @@
+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 UserTypeConfiguration : IEntityTypeConfiguration<UserType>
+ {
+ public void Configure(EntityTypeBuilder<UserType> builder)
+ {
+ builder.HasKey(x => x.Id);
+
+ builder.HasIndex(x => x.Name)
+ .IsUnique();
+
+ builder.Property(x => x.Name)
+ .IsRequired()
+ .HasColumnType("character varying(50)");
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.Designer.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.Designer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..55e1f5f49e8544cbbf09330bfa0a8de8cd5c0217
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.Designer.cs
@@ -0,0 +1,240 @@
+// <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("20201013232333_initial")]
+ partial class initial
+ {
+ 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.Course", 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("Courses");
+ });
+
+ 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>("UserId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityCard")
+ .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.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>("UserId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityCard")
+ .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.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>("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("UserTypeId");
+
+ b.HasIndex("Username")
+ .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.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.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.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.UserType", "UserType")
+ .WithMany()
+ .HasForeignKey("UserTypeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.cs
new file mode 100644
index 0000000000000000000000000000000000000000..165df2e421450b2dfddc5b8947aa41f3eb9efaa7
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/20201013232333_initial.cs
@@ -0,0 +1,233 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+namespace Tsi1.DataLayer.Migrations
+{
+ public partial class initial : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Courses",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ Name = table.Column<string>(type: "character varying(50)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Courses", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Professors",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ UserId = table.Column<int>(nullable: false),
+ IdentityCard = table.Column<string>(type: "character varying(50)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Professors", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Students",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ UserId = table.Column<int>(nullable: false),
+ IdentityCard = table.Column<string>(type: "character varying(50)", nullable: false),
+ Age = table.Column<int>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Students", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserTypes",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ Name = table.Column<string>(type: "character varying(50)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserTypes", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ProfessorCourses",
+ columns: table => new
+ {
+ ProfessorId = table.Column<int>(nullable: false),
+ CourseId = table.Column<int>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ProfessorCourses", x => new { x.ProfessorId, x.CourseId });
+ table.ForeignKey(
+ name: "FK_ProfessorCourses_Courses_CourseId",
+ column: x => x.CourseId,
+ principalTable: "Courses",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_ProfessorCourses_Professors_ProfessorId",
+ column: x => x.ProfessorId,
+ principalTable: "Professors",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "StudentCourses",
+ columns: table => new
+ {
+ StudentId = table.Column<int>(nullable: false),
+ CourseId = table.Column<int>(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_StudentCourses", x => new { x.StudentId, x.CourseId });
+ table.ForeignKey(
+ name: "FK_StudentCourses_Courses_CourseId",
+ column: x => x.CourseId,
+ principalTable: "Courses",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_StudentCourses_Students_StudentId",
+ column: x => x.StudentId,
+ principalTable: "Students",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Users",
+ columns: table => new
+ {
+ Id = table.Column<int>(nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ UserTypeId = table.Column<int>(nullable: false),
+ StudentId = table.Column<int>(nullable: true),
+ ProfessorId = table.Column<int>(nullable: true),
+ Username = table.Column<string>(type: "character varying(50)", nullable: false),
+ Password = table.Column<string>(type: "character varying(255)", nullable: false),
+ FirstName = table.Column<string>(type: "character varying(255)", nullable: false),
+ LastName = table.Column<string>(type: "character varying(255)", nullable: false),
+ Email = table.Column<string>(type: "character varying(255)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Users", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Users_Professors_ProfessorId",
+ column: x => x.ProfessorId,
+ principalTable: "Professors",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Users_Students_StudentId",
+ column: x => x.StudentId,
+ principalTable: "Students",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Users_UserTypes_UserTypeId",
+ column: x => x.UserTypeId,
+ principalTable: "UserTypes",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Courses_Name",
+ table: "Courses",
+ column: "Name",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_ProfessorCourses_CourseId",
+ table: "ProfessorCourses",
+ column: "CourseId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Professors_IdentityCard",
+ table: "Professors",
+ column: "IdentityCard",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_StudentCourses_CourseId",
+ table: "StudentCourses",
+ column: "CourseId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Students_IdentityCard",
+ table: "Students",
+ column: "IdentityCard",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_ProfessorId",
+ table: "Users",
+ column: "ProfessorId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_StudentId",
+ table: "Users",
+ column: "StudentId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_UserTypeId",
+ table: "Users",
+ column: "UserTypeId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Users_Username",
+ table: "Users",
+ column: "Username",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserTypes_Name",
+ table: "UserTypes",
+ column: "Name",
+ unique: true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "ProfessorCourses");
+
+ migrationBuilder.DropTable(
+ name: "StudentCourses");
+
+ migrationBuilder.DropTable(
+ name: "Users");
+
+ migrationBuilder.DropTable(
+ name: "Courses");
+
+ migrationBuilder.DropTable(
+ name: "Professors");
+
+ migrationBuilder.DropTable(
+ name: "Students");
+
+ migrationBuilder.DropTable(
+ name: "UserTypes");
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
new file mode 100644
index 0000000000000000000000000000000000000000..036e9605f4f8d0d7d8f6da51b64a99e3b41e8dcc
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Migrations/Tsi1ContextModelSnapshot.cs
@@ -0,0 +1,238 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Tsi1.DataLayer;
+
+namespace Tsi1.DataLayer.Migrations
+{
+ [DbContext(typeof(Tsi1Context))]
+ partial class Tsi1ContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(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.Course", 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("Courses");
+ });
+
+ 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>("UserId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityCard")
+ .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.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>("UserId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IdentityCard")
+ .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.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>("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("UserTypeId");
+
+ b.HasIndex("Username")
+ .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.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.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.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.UserType", "UserType")
+ .WithMany()
+ .HasForeignKey("UserTypeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj b/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..f7ccef3b5756bb86b63f32218d76f276a30f1c08
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1.DataLayer.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp3.1</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.4">
+ <PrivateAssets>all</PrivateAssets>
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ </PackageReference>
+ <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="3.1.9" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.9" />
+ <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="3.1.4" />
+ </ItemGroup>
+
+</Project>
diff --git a/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs
new file mode 100644
index 0000000000000000000000000000000000000000..632d64b29f9a63df47bea3b98e4a4edfd79ddbf4
--- /dev/null
+++ b/Tsi1.Api/Tsi1.DataLayer/Tsi1Context.cs
@@ -0,0 +1,33 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Tsi1.DataLayer.Entities;
+using Tsi1.DataLayer.EntityConfiguration;
+
+namespace Tsi1.DataLayer
+{
+ public class Tsi1Context : DbContext
+ {
+ public DbSet<User> Users { get; set; }
+ public DbSet<UserType> UserTypes { get; set; }
+ public DbSet<Student> Students { get; set; }
+ public DbSet<StudentCourse> StudentCourses { get; set; }
+ public DbSet<Professor> Professors { get; set; }
+ public DbSet<ProfessorCourse> ProfessorCourses { get; set; }
+ public DbSet<Course> Courses { get; set; }
+
+ public Tsi1Context(DbContextOptions options) : base(options) { }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.ApplyConfiguration(new UserConfiguration());
+ modelBuilder.ApplyConfiguration(new UserTypeConfiguration());
+ modelBuilder.ApplyConfiguration(new StudentConfiguration());
+ modelBuilder.ApplyConfiguration(new StudentCourseConfiguration());
+ modelBuilder.ApplyConfiguration(new ProfessorConfiguration());
+ modelBuilder.ApplyConfiguration(new ProfessorCourseConfiguration());
+ modelBuilder.ApplyConfiguration(new CourseConfiguration());
+ }
+ }
+}