diff --git a/.gitignore b/.gitignore index fda7eec6..c0cc8cf0 100644 --- a/.gitignore +++ b/.gitignore @@ -338,4 +338,4 @@ IdentityServer/tempkey.rsa !/API/Uploads/Images/.gitkeep ### -rabbitmq/data/ +rabbitmq/data/ \ No newline at end of file diff --git a/API/Controllers/ProjectController.cs b/API/Controllers/ProjectController.cs index be37a42d..9b21ebbb 100644 --- a/API/Controllers/ProjectController.cs +++ b/API/Controllers/ProjectController.cs @@ -34,7 +34,6 @@ using System.Linq; using System.Net; using System.Threading.Tasks; -using File = Models.File; namespace API.Controllers { @@ -349,7 +348,7 @@ await callToActionOptionService.GetCallToActionOptionFromValueAsync( } Project project = mapper.Map(projectResource); - File file = await fileService.FindAsync(projectResource.FileId); + Models.File file = await fileService.FindAsync(projectResource.FileId); if(projectResource.FileId != 0 && file == null) @@ -363,6 +362,23 @@ await callToActionOptionService.GetCallToActionOptionFromValueAsync( return BadRequest(problem); } + foreach(int projectResourceImageId in projectResource.ImageIds) + { + Models.File image = await fileService.FindAsync(projectResourceImageId); + if(image == null) + { + ProblemDetails problem = new ProblemDetails + { + Title = "Image was not found.", + Detail = "The specified image was not found while creating project.", + Instance = "B040FAAD-FD22-4C77-822E-C498DFA1A9CB" + }; + return BadRequest(problem); + } + + project.Images.Add(image); + } + project.ProjectIcon = file; project.User = await HttpContext.GetContextUser(userService) .ConfigureAwait(false); @@ -511,7 +527,7 @@ await callToActionOptionService.GetCallToActionOptionFromValueAsync( } // Upload the new file if there is one - File file = null; + Models.File file = null; if(projectResource.FileId != 0) { if(project.ProjectIconId != 0 && @@ -519,7 +535,7 @@ await callToActionOptionService.GetCallToActionOptionFromValueAsync( { if(project.ProjectIconId != projectResource.FileId) { - File fileToDelete = await fileService.FindAsync(project.ProjectIconId.Value); + Models.File fileToDelete = await fileService.FindAsync(project.ProjectIconId.Value); // Remove the file from the filesystem fileUploader.DeleteFileFromDirectory(fileToDelete); @@ -550,6 +566,23 @@ await callToActionOptionService.GetCallToActionOptionFromValueAsync( } } + foreach(int projectResourceImageId in projectResource.ImageIds) + { + Models.File image = await fileService.FindAsync(projectResourceImageId); + if(image == null) + { + ProblemDetails problem = new ProblemDetails + { + Title = "Image was not found.", + Detail = "The specified image was not found while creating project.", + Instance = "FC816E40-31A6-4187-BEBA-D22F06019F8F" + }; + return BadRequest(problem); + } + + project.Images.Add(image); + } + await projectCategoryService.ClearProjectCategories(project); if(projectResource.Categories != null) { @@ -639,7 +672,7 @@ public async Task DeleteProject(int projectId) if(project.ProjectIconId.HasValue) { // We need to delete the old file. - File fileToDelete = await fileService.FindAsync(project.ProjectIconId.Value); + Models.File fileToDelete = await fileService.FindAsync(project.ProjectIconId.Value); try { // Remove the file from the database diff --git a/API/Resources/ProjectResource.cs b/API/Resources/ProjectResource.cs index e7eabb91..92f543c7 100644 --- a/API/Resources/ProjectResource.cs +++ b/API/Resources/ProjectResource.cs @@ -71,6 +71,11 @@ public class ProjectResource /// public ICollection Categories { get; set; } + /// + /// This gets or sets the image ID's + /// + public IEnumerable ImageIds { get; set; } = new List(); + } } diff --git a/API/Resources/ProjectResourceResult.cs b/API/Resources/ProjectResourceResult.cs index 3955d8e2..09c51d47 100644 --- a/API/Resources/ProjectResourceResult.cs +++ b/API/Resources/ProjectResourceResult.cs @@ -97,6 +97,11 @@ public class ProjectResourceResult /// public List Likes { get; set; } + /// + /// This gets or sets the images in de project. + /// + public List Images { get; set; } + /// /// Sets or gets if project is visible to institute members only or not /// diff --git a/CHANGELOG.md b/CHANGELOG.md index f02dd781..625d146f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added image to highlights - [#431](https://github.com/DigitalExcellence/dex-backend/issues/431) +- Added functionality to add multiples images to a project - [#430](https://github.com/DigitalExcellence/dex-backend/issues/430) ### Changed diff --git a/Data/Migrations/20210520120425_AddedImagesToProjects.Designer.cs b/Data/Migrations/20210520120425_AddedImagesToProjects.Designer.cs new file mode 100644 index 00000000..6e347847 --- /dev/null +++ b/Data/Migrations/20210520120425_AddedImagesToProjects.Designer.cs @@ -0,0 +1,742 @@ +// +using System; +using Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace _4_Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20210520120425_AddedImagesToProjects")] + partial class AddedImagesToProjects + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.3") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Models.CallToAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("OptionValue") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("CallToAction"); + }); + + modelBuilder.Entity("Models.CallToActionOption", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("CallToActionOption"); + }); + + modelBuilder.Entity("Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Category"); + }); + + modelBuilder.Entity("Models.Collaborator", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("FullName") + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("Role") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.ToTable("Collaborators"); + }); + + modelBuilder.Entity("Models.DataSource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Guid") + .HasColumnType("nvarchar(max)"); + + b.Property("IconId") + .HasColumnType("int"); + + b.Property("IsVisible") + .HasColumnType("bit"); + + b.Property("Title") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("IconId"); + + b.ToTable("DataSource"); + }); + + modelBuilder.Entity("Models.DataSourceWizardPage", b => + { + b.Property("DataSourceId") + .HasColumnType("int"); + + b.Property("WizardPageId") + .HasColumnType("int"); + + b.Property("AuthFlow") + .HasColumnType("bit"); + + b.Property("OrderIndex") + .HasColumnType("int"); + + b.HasKey("DataSourceId", "WizardPageId", "AuthFlow"); + + b.HasIndex("WizardPageId"); + + b.ToTable("DataSourceWizardPage"); + }); + + modelBuilder.Entity("Models.EmbeddedProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Guid") + .HasColumnType("uniqueidentifier"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UserId"); + + b.ToTable("EmbeddedProject"); + }); + + modelBuilder.Entity("Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("Path") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("UploadDateTime") + .HasColumnType("datetime2"); + + b.Property("UploaderId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UploaderId"); + + b.ToTable("File"); + }); + + modelBuilder.Entity("Models.Highlight", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("EndDate") + .HasColumnType("datetime2"); + + b.Property("ImageId") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("StartDate") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("ProjectId"); + + b.ToTable("Highlight"); + }); + + modelBuilder.Entity("Models.Institution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("IdentityId") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Institution"); + }); + + modelBuilder.Entity("Models.Project", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CallToActionId") + .HasColumnType("int"); + + b.Property("Created") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("InstitutePrivate") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProjectIconId") + .HasColumnType("int"); + + b.Property("ShortDescription") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Updated") + .HasColumnType("datetime2"); + + b.Property("Uri") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CallToActionId"); + + b.HasIndex("ProjectIconId"); + + b.HasIndex("UserId"); + + b.ToTable("Project"); + }); + + modelBuilder.Entity("Models.ProjectCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectCategory"); + }); + + modelBuilder.Entity("Models.ProjectInstitution", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("InstitutionId") + .HasColumnType("int"); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("InstitutionId"); + + b.HasIndex("ProjectId"); + + b.ToTable("ProjectInstitution"); + }); + + modelBuilder.Entity("Models.ProjectLike", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Date") + .HasColumnType("datetime2"); + + b.Property("LikedProjectId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("LikedProjectId"); + + b.HasIndex("UserId"); + + b.ToTable("ProjectLike"); + }); + + modelBuilder.Entity("Models.Role", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Role"); + }); + + modelBuilder.Entity("Models.RoleScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("RoleId") + .HasColumnType("int"); + + b.Property("Scope") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("RoleScope"); + }); + + modelBuilder.Entity("Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("AccountCreationDate") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ExpectedGraduationDate") + .HasColumnType("datetime2"); + + b.Property("IdentityId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("InstitutionId") + .HasColumnType("int"); + + b.Property("IsPublic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ProfileUrl") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("InstitutionId"); + + b.HasIndex("RoleId"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Models.UserProject", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ProjectId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ProjectId"); + + b.HasIndex("UserId"); + + b.ToTable("UserProject"); + }); + + modelBuilder.Entity("Models.UserTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserTask"); + }); + + modelBuilder.Entity("Models.UserUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("FollowedUserId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("FollowedUserId"); + + b.HasIndex("UserId"); + + b.ToTable("UserUser"); + }); + + modelBuilder.Entity("Models.WizardPage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("WizardPage"); + }); + + modelBuilder.Entity("Models.Collaborator", b => + { + b.HasOne("Models.Project", null) + .WithMany("Collaborators") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.DataSource", b => + { + b.HasOne("Models.File", "Icon") + .WithMany() + .HasForeignKey("IconId"); + }); + + modelBuilder.Entity("Models.DataSourceWizardPage", b => + { + b.HasOne("Models.DataSource", "DataSource") + .WithMany("DataSourceWizardPages") + .HasForeignKey("DataSourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Models.WizardPage", "WizardPage") + .WithMany("DataSourceWizardPages") + .HasForeignKey("WizardPageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.EmbeddedProject", b => + { + b.HasOne("Models.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Models.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.File", b => + { + b.HasOne("Models.Project", null) + .WithMany("Images") + .HasForeignKey("ProjectId"); + + b.HasOne("Models.User", "Uploader") + .WithMany() + .HasForeignKey("UploaderId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.Highlight", b => + { + b.HasOne("Models.File", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.HasOne("Models.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.Project", b => + { + b.HasOne("Models.CallToAction", "CallToAction") + .WithMany() + .HasForeignKey("CallToActionId"); + + b.HasOne("Models.File", "ProjectIcon") + .WithMany() + .HasForeignKey("ProjectIconId"); + + b.HasOne("Models.User", "User") + .WithMany("Projects") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.ProjectCategory", b => + { + b.HasOne("Models.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Models.Project", "Project") + .WithMany("Categories") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.ProjectInstitution", b => + { + b.HasOne("Models.Institution", "Institution") + .WithMany() + .HasForeignKey("InstitutionId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Models.Project", "Project") + .WithMany("LinkedInstitutions") + .HasForeignKey("ProjectId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.ProjectLike", b => + { + b.HasOne("Models.Project", "LikedProject") + .WithMany("Likes") + .HasForeignKey("LikedProjectId"); + + b.HasOne("Models.User", "ProjectLiker") + .WithMany("LikedProjectsByUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.RoleScope", b => + { + b.HasOne("Models.Role", null) + .WithMany("Scopes") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.User", b => + { + b.HasOne("Models.Institution", "Institution") + .WithMany() + .HasForeignKey("InstitutionId"); + + b.HasOne("Models.Role", "Role") + .WithMany() + .HasForeignKey("RoleId"); + }); + + modelBuilder.Entity("Models.UserProject", b => + { + b.HasOne("Models.Project", "Project") + .WithMany() + .HasForeignKey("ProjectId"); + + b.HasOne("Models.User", "User") + .WithMany("UserProject") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Models.UserTask", b => + { + b.HasOne("Models.User", "User") + .WithMany("UserTasks") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Models.UserUser", b => + { + b.HasOne("Models.User", "FollowedUser") + .WithMany("FollowedUsers") + .HasForeignKey("FollowedUserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Data/Migrations/20210520120425_AddedImagesToProjects.cs b/Data/Migrations/20210520120425_AddedImagesToProjects.cs new file mode 100644 index 00000000..049135a0 --- /dev/null +++ b/Data/Migrations/20210520120425_AddedImagesToProjects.cs @@ -0,0 +1,43 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace _4_Data.Migrations +{ + public partial class AddedImagesToProjects : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ProjectId", + table: "File", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_File_ProjectId", + table: "File", + column: "ProjectId"); + + migrationBuilder.AddForeignKey( + name: "FK_File_Project_ProjectId", + table: "File", + column: "ProjectId", + principalTable: "Project", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_File_Project_ProjectId", + table: "File"); + + migrationBuilder.DropIndex( + name: "IX_File_ProjectId", + table: "File"); + + migrationBuilder.DropColumn( + name: "ProjectId", + table: "File"); + } + } +} diff --git a/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/Data/Migrations/ApplicationDbContextModelSnapshot.cs index 10a11782..749ddce9 100644 --- a/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -187,6 +187,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("ProjectId") + .HasColumnType("int"); + b.Property("UploadDateTime") .HasColumnType("datetime2"); @@ -195,6 +198,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); + b.HasIndex("ProjectId"); + b.HasIndex("UploaderId"); b.ToTable("File"); @@ -593,6 +598,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Models.File", b => { + b.HasOne("Models.Project", null) + .WithMany("Images") + .HasForeignKey("ProjectId"); + b.HasOne("Models.User", "Uploader") .WithMany() .HasForeignKey("UploaderId") diff --git a/Models/Project.cs b/Models/Project.cs index be4c1dba..5a7d3cec 100644 --- a/Models/Project.cs +++ b/Models/Project.cs @@ -31,6 +31,7 @@ public Project() { Collaborators = new List(); LinkedInstitutions = new List(); + Images = new List(); } public int Id { get; set; } @@ -79,6 +80,8 @@ public Project() public List Categories { get; set; } + public List Images { get; set; } + /// /// Checks if the user can access the project based on diff --git a/Repositories/ProjectRepository.cs b/Repositories/ProjectRepository.cs index 6735ffc4..89ae6760 100644 --- a/Repositories/ProjectRepository.cs +++ b/Repositories/ProjectRepository.cs @@ -159,6 +159,7 @@ public override async Task FindAsync(int id) .Where(s => s.Id == id) .Include(p => p.ProjectIcon) .Include(p => p.CallToAction) + .Include(p => p.Images) .SingleOrDefaultAsync(); if(project != null) @@ -202,6 +203,7 @@ public virtual async Task> GetAllWithUsersCollaboratorsAndInstitut .Include(p => p.Collaborators) .Include(p => p.Likes) .Include(p => p.LinkedInstitutions) + .Include(p => p.Images) .Include(p => p.Categories) .ThenInclude(c => c.Category) //Don't get the description for performance reasons. @@ -300,6 +302,7 @@ public async Task FindWithUserCollaboratorsAndInstitutionsAsync(int id) .Include(p => p.User) .Include(p => p.ProjectIcon) .Include(p => p.CallToAction) + .Include(p => p.Images) .Where(p => p.Id == id) .FirstOrDefaultAsync(); if(project != null) @@ -442,6 +445,7 @@ public async Task> GetUserProjects(int userId) IEnumerable projects = await GetDbSet() .Include(p => p.Collaborators) .Include(p => p.ProjectIcon) + .Include(p => p.Images) .Where(p => p.UserId == userId) .ToListAsync();