diff --git a/AskFm/AskFm.API/AskFm.API.csproj b/AskFm/AskFm.API/AskFm.API.csproj index 2c79a8c..f10f941 100644 --- a/AskFm/AskFm.API/AskFm.API.csproj +++ b/AskFm/AskFm.API/AskFm.API.csproj @@ -8,6 +8,7 @@ + diff --git a/AskFm/AskFm.API/Program.cs b/AskFm/AskFm.API/Program.cs index 13232f4..ce07055 100644 --- a/AskFm/AskFm.API/Program.cs +++ b/AskFm/AskFm.API/Program.cs @@ -1,11 +1,14 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity; using AskFm.DAL; +using AskFm.DAL.Models; using AskFm.DAL.Interfaces; using AskFm.DAL.Repositories; using DotNetEnv; using Microsoft.EntityFrameworkCore.Proxies; namespace AskFm.API; + public class Program { public static void Main(string[] args) @@ -24,10 +27,16 @@ public static void Main(string[] args) { throw new Exception("Connection string is null"); } + builder.Services.AddDbContext(options => options .UseLazyLoadingProxies() .UseSqlServer(ConnectionString)); + + builder.Services.AddIdentity>() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + builder.Services.AddScoped(); diff --git a/AskFm/AskFm.DAL/AppDbContext.cs b/AskFm/AskFm.DAL/AppDbContext.cs index 70b80cd..4f35d3d 100644 --- a/AskFm/AskFm.DAL/AppDbContext.cs +++ b/AskFm/AskFm.DAL/AppDbContext.cs @@ -1,16 +1,19 @@ +using System.Data; using AskFm.DAL.Models; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Thread = AskFm.DAL.Models.Thread; namespace AskFm.DAL; -public class AppDbContext : DbContext +public class AppDbContext : IdentityDbContext, int> { public AppDbContext(DbContextOptions options) : base(options) { } - public DbSet Users { get; set; } + public DbSet Users { get; set; } public DbSet Threads { get; set; } public DbSet Comments { get; set; } public DbSet Follows { get; set; } @@ -23,5 +26,59 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(typeof(AppDbContext).Assembly); + + foreach (var entityType in modelBuilder.Model.GetEntityTypes() + .Where(t => typeof(ITrackable).IsAssignableFrom(t.ClrType))) + { + + modelBuilder.Entity(entityType.ClrType).Property("DeletedAt") + .HasColumnType("DATETIME"); + + modelBuilder.Entity(entityType.ClrType).Property("UpdatedAt") + .HasColumnType("DATETIME"); + + modelBuilder.Entity(entityType.ClrType).Property("CreatedAt") + .HasColumnType("DATETIME"); + + modelBuilder.Entity(entityType.ClrType).Property("IsDeleted") + .HasColumnType("BIT") + .HasDefaultValue(false); + } + + } + + public override Task SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken()) + { + _fillTrackableInfromation(); + return base.SaveChangesAsync(cancellationToken); + + } + public override int SaveChanges() + { + _fillTrackableInfromation(); + return base.SaveChanges(); + } + private void _fillTrackableInfromation() + { + foreach (var entry in ChangeTracker.Entries()) + { + switch (entry.State) + { + case EntityState.Added: + entry.Entity.CreatedAt = DateTime.UtcNow; + entry.Entity.DeletedAt = DateTime.UtcNow;; + entry.Entity.UpdatedAt = DateTime.UtcNow; + entry.Entity.IsDeleted = false; + break; + case EntityState.Modified: + entry.Entity.UpdatedAt = DateTime.UtcNow; + break; + case EntityState.Deleted: + entry.Entity.IsDeleted = true; + entry.Entity.DeletedAt = DateTime.UtcNow; + entry.State = EntityState.Modified; + break; + } + } } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/AskFm.DAL.csproj b/AskFm/AskFm.DAL/AskFm.DAL.csproj index 4b32852..c77d955 100644 --- a/AskFm/AskFm.DAL/AskFm.DAL.csproj +++ b/AskFm/AskFm.DAL/AskFm.DAL.csproj @@ -8,6 +8,7 @@ + all diff --git a/AskFm/AskFm.DAL/Interfaces/IUnitOfWork.cs b/AskFm/AskFm.DAL/Interfaces/IUnitOfWork.cs index 4215d99..108f184 100644 --- a/AskFm/AskFm.DAL/Interfaces/IUnitOfWork.cs +++ b/AskFm/AskFm.DAL/Interfaces/IUnitOfWork.cs @@ -5,7 +5,7 @@ namespace AskFm.DAL.Interfaces; public interface IUnitOfWork : IDisposable { - IRepository Users { get; } + IRepository Users { get; } IRepository Threads { get; } IRepository SavedThreads { get; } IRepository ThreadLikes { get; } diff --git a/AskFm/AskFm.DAL/Interfaces/IUserRepository.cs b/AskFm/AskFm.DAL/Interfaces/IUserRepository.cs index b35ed8e..20cf2e5 100644 --- a/AskFm/AskFm.DAL/Interfaces/IUserRepository.cs +++ b/AskFm/AskFm.DAL/Interfaces/IUserRepository.cs @@ -2,8 +2,8 @@ namespace AskFm.DAL.Interfaces; -public interface IUserRepository : IRepository +public interface IApplicationUserRepository : IRepository { - Task GetByUsernameAsync(string username); + Task GetByUsernameAsync(string username); } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.Designer.cs b/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.Designer.cs new file mode 100644 index 0000000..c118480 --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.Designer.cs @@ -0,0 +1,500 @@ +// +using System; +using AskFm.DAL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250810015924_Soft_Delete")] + partial class Soft_Delete + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LikeCount") + .HasColumnType("int"); + + b.Property("ParentCommentId") + .HasColumnType("int"); + + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ParentCommentId"); + + b.HasIndex("ThreadId"); + + b.HasIndex("UserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CommentId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("UserId", "CommentId"); + + b.HasIndex("CommentId"); + + b.ToTable("CommentLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.Property("FollowerId") + .HasColumnType("int"); + + b.Property("FollowedId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("Follows"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("ResourceId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("isRead") + .HasColumnType("bit"); + + b.Property("jsonContent") + .IsRequired() + .HasColumnType("NVARCHAR"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.Property("SavedThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("SavedThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("SavedThreads"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnswerContent") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("AskedId") + .HasColumnType("int"); + + b.Property("AskerId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("QuestionContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("isAnonymous") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("AskedId"); + + b.HasIndex("AskerId"); + + b.ToTable("Thread", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("ThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AvatarPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("FollowersCount") + .HasColumnType("int"); + + b.Property("FollowingCount") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LastSeen") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(225) + .HasColumnType("nvarchar(225)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "ParentComment") + .WithMany("Replies") + .HasForeignKey("ParentCommentId"); + + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("Comments") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("Comments") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("ParentComment"); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "Comment") + .WithMany("CommentLikes") + .HasForeignKey("CommentId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("CommentLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Comment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.HasOne("AskFm.DAL.Models.User", "Followed") + .WithMany("Followers") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "Follower") + .WithMany("Following") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("SavedThreads") + .HasForeignKey("SavedThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("SavedThreads") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.HasOne("AskFm.DAL.Models.User", "Asked") + .WithMany("ReceivedThreads") + .HasForeignKey("AskedId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "Asker") + .WithMany("AskedThreads") + .HasForeignKey("AskerId"); + + b.Navigation("Asked"); + + b.Navigation("Asker"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("ThreadLikes") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("ThreadLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Navigation("CommentLikes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Navigation("Comments"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.User", b => + { + b.Navigation("AskedThreads"); + + b.Navigation("CommentLikes"); + + b.Navigation("Comments"); + + b.Navigation("Followers"); + + b.Navigation("Following"); + + b.Navigation("Notifications"); + + b.Navigation("ReceivedThreads"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.cs b/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.cs new file mode 100644 index 0000000..42bcab7 --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810015924_Soft_Delete.cs @@ -0,0 +1,195 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + /// + public partial class Soft_Delete : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "Users", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "Users", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "ThreadLikes", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "ThreadLikes", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "Thread", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "Thread", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "SavedThreads", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "SavedThreads", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "Notifications", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "Notifications", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "Follows", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "Follows", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "Comments", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "Comments", + type: "BIT", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "DeletedAt", + table: "CommentLikes", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "IsDeleted", + table: "CommentLikes", + type: "BIT", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "Users"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "Users"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "ThreadLikes"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "ThreadLikes"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "Thread"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "Thread"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "SavedThreads"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "SavedThreads"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "Notifications"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "Notifications"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "Follows"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "Follows"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "Comments"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "Comments"); + + migrationBuilder.DropColumn( + name: "DeletedAt", + table: "CommentLikes"); + + migrationBuilder.DropColumn( + name: "IsDeleted", + table: "CommentLikes"); + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.Designer.cs b/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.Designer.cs new file mode 100644 index 0000000..17a292e --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.Designer.cs @@ -0,0 +1,502 @@ +// +using System; +using AskFm.DAL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250810021444_set_no_action_OnDelete")] + partial class set_no_action_OnDelete + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LikeCount") + .HasColumnType("int"); + + b.Property("ParentCommentId") + .HasColumnType("int"); + + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ParentCommentId"); + + b.HasIndex("ThreadId"); + + b.HasIndex("UserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CommentId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("UserId", "CommentId"); + + b.HasIndex("CommentId"); + + b.ToTable("CommentLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.Property("FollowerId") + .HasColumnType("int"); + + b.Property("FollowedId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("Follows"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("ResourceId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("isRead") + .HasColumnType("bit"); + + b.Property("jsonContent") + .IsRequired() + .HasColumnType("NVARCHAR"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.Property("SavedThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("SavedThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("SavedThreads"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnswerContent") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("AskedId") + .HasColumnType("int"); + + b.Property("AskerId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("QuestionContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("isAnonymous") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("AskedId"); + + b.HasIndex("AskerId"); + + b.ToTable("Thread", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("ThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AvatarPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("FollowersCount") + .HasColumnType("int"); + + b.Property("FollowingCount") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LastSeen") + .HasColumnType("datetime2"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Password") + .IsRequired() + .HasMaxLength(225) + .HasColumnType("nvarchar(225)"); + + b.Property("Username") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "ParentComment") + .WithMany("Replies") + .HasForeignKey("ParentCommentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("Comments") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("Comments") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("ParentComment"); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "Comment") + .WithMany("CommentLikes") + .HasForeignKey("CommentId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("CommentLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Comment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.HasOne("AskFm.DAL.Models.User", "Followed") + .WithMany("Followers") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "Follower") + .WithMany("Following") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("SavedThreads") + .HasForeignKey("SavedThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("SavedThreads") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.HasOne("AskFm.DAL.Models.User", "Asked") + .WithMany("ReceivedThreads") + .HasForeignKey("AskedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "Asker") + .WithMany("AskedThreads") + .HasForeignKey("AskerId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Asked"); + + b.Navigation("Asker"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("ThreadLikes") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.User", "User") + .WithMany("ThreadLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Navigation("CommentLikes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Navigation("Comments"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.User", b => + { + b.Navigation("AskedThreads"); + + b.Navigation("CommentLikes"); + + b.Navigation("Comments"); + + b.Navigation("Followers"); + + b.Navigation("Following"); + + b.Navigation("Notifications"); + + b.Navigation("ReceivedThreads"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.cs b/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.cs new file mode 100644 index 0000000..9565fab --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810021444_set_no_action_OnDelete.cs @@ -0,0 +1,133 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + /// + public partial class set_no_action_OnDelete : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes"); + + migrationBuilder.DropForeignKey( + name: "FK_Comments_Thread_ThreadId", + table: "Comments"); + + migrationBuilder.DropForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes"); + + migrationBuilder.AddForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Comments_Thread_ThreadId", + table: "Comments", + column: "ThreadId", + principalTable: "Thread", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread", + column: "AskedId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes"); + + migrationBuilder.DropForeignKey( + name: "FK_Comments_Thread_ThreadId", + table: "Comments"); + + migrationBuilder.DropForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes"); + + migrationBuilder.AddForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Comments_Thread_ThreadId", + table: "Comments", + column: "ThreadId", + principalTable: "Thread", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications", + column: "UserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread", + column: "AskedId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.Designer.cs b/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.Designer.cs new file mode 100644 index 0000000..1612fcc --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.Designer.cs @@ -0,0 +1,728 @@ +// +using System; +using AskFm.DAL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250810034350_using_identity")] + partial class using_identity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("AvatarPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FollowersCount") + .HasColumnType("int"); + + b.Property("FollowingCount") + .HasColumnType("int"); + + b.Property("IsDeleted") + .HasColumnType("bit"); + + b.Property("LastSeen") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LikeCount") + .HasColumnType("int"); + + b.Property("ParentCommentId") + .HasColumnType("int"); + + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ParentCommentId"); + + b.HasIndex("ThreadId"); + + b.HasIndex("UserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CommentId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("UserId", "CommentId"); + + b.HasIndex("CommentId"); + + b.ToTable("CommentLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.Property("FollowerId") + .HasColumnType("int"); + + b.Property("FollowedId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("Follows"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("ResourceId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("isRead") + .HasColumnType("bit"); + + b.Property("jsonContent") + .IsRequired() + .HasColumnType("NVARCHAR"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.Property("SavedThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("SavedThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("SavedThreads"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnswerContent") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("AskedId") + .HasColumnType("int"); + + b.Property("AskerId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("QuestionContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("isAnonymous") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("AskedId"); + + b.HasIndex("AskerId"); + + b.ToTable("Thread", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("datetime"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.HasKey("ThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ThreadLikes"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "ParentComment") + .WithMany("Replies") + .HasForeignKey("ParentCommentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("Comments") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("Comments") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("ParentComment"); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "Comment") + .WithMany("CommentLikes") + .HasForeignKey("CommentId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("CommentLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Comment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Followed") + .WithMany("Followers") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Follower") + .WithMany("Following") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("SavedThreads") + .HasForeignKey("SavedThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("SavedThreads") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asked") + .WithMany("ReceivedThreads") + .HasForeignKey("AskedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asker") + .WithMany("AskedThreads") + .HasForeignKey("AskerId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Asked"); + + b.Navigation("Asker"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("ThreadLikes") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("ThreadLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => + { + b.Navigation("AskedThreads"); + + b.Navigation("CommentLikes"); + + b.Navigation("Comments"); + + b.Navigation("Followers"); + + b.Navigation("Following"); + + b.Navigation("Notifications"); + + b.Navigation("ReceivedThreads"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Navigation("CommentLikes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Navigation("Comments"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.cs b/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.cs new file mode 100644 index 0000000..6308ec5 --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250810034350_using_identity.cs @@ -0,0 +1,641 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + /// + public partial class using_identity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes"); + + migrationBuilder.DropForeignKey( + name: "FK_Comments_Users_UserId", + table: "Comments"); + + migrationBuilder.DropForeignKey( + name: "FK_Follows_Users_FollowedId", + table: "Follows"); + + migrationBuilder.DropForeignKey( + name: "FK_Follows_Users_FollowerId", + table: "Follows"); + + migrationBuilder.DropForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications"); + + migrationBuilder.DropForeignKey( + name: "FK_SavedThreads_Users_UserId", + table: "SavedThreads"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_Users_AskerId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Users", + table: "Users"); + + migrationBuilder.DropColumn( + name: "Password", + table: "Users"); + + migrationBuilder.RenameTable( + name: "Users", + newName: "AspNetUsers"); + + migrationBuilder.RenameColumn( + name: "Username", + table: "AspNetUsers", + newName: "UserName"); + + migrationBuilder.RenameIndex( + name: "IX_Users_Username", + table: "AspNetUsers", + newName: "IX_AspNetUsers_UserName"); + + migrationBuilder.AlterColumn( + name: "UserName", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(450)"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "AspNetUsers", + type: "bit", + nullable: false, + oldClrType: typeof(bool), + oldType: "BIT", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "DeletedAt", + table: "AspNetUsers", + type: "datetime2", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AddColumn( + name: "AccessFailedCount", + table: "AspNetUsers", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "ConcurrencyStamp", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "EmailConfirmed", + table: "AspNetUsers", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "LockoutEnabled", + table: "AspNetUsers", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "LockoutEnd", + table: "AspNetUsers", + type: "datetimeoffset", + nullable: true); + + migrationBuilder.AddColumn( + name: "NormalizedEmail", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true); + + migrationBuilder.AddColumn( + name: "NormalizedUserName", + table: "AspNetUsers", + type: "nvarchar(256)", + maxLength: 256, + nullable: true); + + migrationBuilder.AddColumn( + name: "PasswordHash", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "PhoneNumber", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "PhoneNumberConfirmed", + table: "AspNetUsers", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "SecurityStamp", + table: "AspNetUsers", + type: "nvarchar(max)", + nullable: true); + + migrationBuilder.AddColumn( + name: "TwoFactorEnabled", + table: "AspNetUsers", + type: "bit", + nullable: false, + defaultValue: false); + + migrationBuilder.AddPrimaryKey( + name: "PK_AspNetUsers", + table: "AspNetUsers", + column: "Id"); + + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Name = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + UserId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + ProviderKey = table.Column(type: "nvarchar(450)", nullable: false), + ProviderDisplayName = table.Column(type: "nvarchar(max)", nullable: true), + UserId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + LoginProvider = table.Column(type: "nvarchar(450)", nullable: false), + Name = table.Column(type: "nvarchar(450)", nullable: false), + Value = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + RoleId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "nvarchar(max)", nullable: true), + ClaimValue = table.Column(type: "nvarchar(max)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true, + filter: "[NormalizedUserName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true, + filter: "[NormalizedName] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.AddForeignKey( + name: "FK_CommentLikes_AspNetUsers_UserId", + table: "CommentLikes", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Comments_AspNetUsers_UserId", + table: "Comments", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Follows_AspNetUsers_FollowedId", + table: "Follows", + column: "FollowedId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Follows_AspNetUsers_FollowerId", + table: "Follows", + column: "FollowerId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Notifications_AspNetUsers_UserId", + table: "Notifications", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_SavedThreads_AspNetUsers_UserId", + table: "SavedThreads", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_AspNetUsers_AskedId", + table: "Thread", + column: "AskedId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_AspNetUsers_AskerId", + table: "Thread", + column: "AskerId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ThreadLikes_AspNetUsers_UserId", + table: "ThreadLikes", + column: "UserId", + principalTable: "AspNetUsers", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_CommentLikes_AspNetUsers_UserId", + table: "CommentLikes"); + + migrationBuilder.DropForeignKey( + name: "FK_Comments_AspNetUsers_UserId", + table: "Comments"); + + migrationBuilder.DropForeignKey( + name: "FK_Follows_AspNetUsers_FollowedId", + table: "Follows"); + + migrationBuilder.DropForeignKey( + name: "FK_Follows_AspNetUsers_FollowerId", + table: "Follows"); + + migrationBuilder.DropForeignKey( + name: "FK_Notifications_AspNetUsers_UserId", + table: "Notifications"); + + migrationBuilder.DropForeignKey( + name: "FK_SavedThreads_AspNetUsers_UserId", + table: "SavedThreads"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_AspNetUsers_AskedId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_Thread_AspNetUsers_AskerId", + table: "Thread"); + + migrationBuilder.DropForeignKey( + name: "FK_ThreadLikes_AspNetUsers_UserId", + table: "ThreadLikes"); + + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropPrimaryKey( + name: "PK_AspNetUsers", + table: "AspNetUsers"); + + migrationBuilder.DropIndex( + name: "EmailIndex", + table: "AspNetUsers"); + + migrationBuilder.DropIndex( + name: "UserNameIndex", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "AccessFailedCount", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "ConcurrencyStamp", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "EmailConfirmed", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "LockoutEnabled", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "LockoutEnd", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "NormalizedEmail", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "NormalizedUserName", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "PasswordHash", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "PhoneNumber", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "PhoneNumberConfirmed", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "SecurityStamp", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "TwoFactorEnabled", + table: "AspNetUsers"); + + migrationBuilder.RenameTable( + name: "AspNetUsers", + newName: "Users"); + + migrationBuilder.RenameColumn( + name: "UserName", + table: "Users", + newName: "Username"); + + migrationBuilder.RenameIndex( + name: "IX_AspNetUsers_UserName", + table: "Users", + newName: "IX_Users_Username"); + + migrationBuilder.AlterColumn( + name: "Username", + table: "Users", + type: "nvarchar(450)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(256)", + oldMaxLength: 256); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "Users", + type: "BIT", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "bit"); + + migrationBuilder.AlterColumn( + name: "DeletedAt", + table: "Users", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AddColumn( + name: "Password", + table: "Users", + type: "nvarchar(225)", + maxLength: 225, + nullable: false, + defaultValue: ""); + + migrationBuilder.AddPrimaryKey( + name: "PK_Users", + table: "Users", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_CommentLikes_Users_UserId", + table: "CommentLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Comments_Users_UserId", + table: "Comments", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Follows_Users_FollowedId", + table: "Follows", + column: "FollowedId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Follows_Users_FollowerId", + table: "Follows", + column: "FollowerId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Notifications_Users_UserId", + table: "Notifications", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_SavedThreads_Users_UserId", + table: "SavedThreads", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_Users_AskedId", + table: "Thread", + column: "AskedId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Thread_Users_AskerId", + table: "Thread", + column: "AskerId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_ThreadLikes_Users_UserId", + table: "ThreadLikes", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.Designer.cs b/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.Designer.cs new file mode 100644 index 0000000..3e74804 --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.Designer.cs @@ -0,0 +1,757 @@ +// +using System; +using AskFm.DAL; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250812150332_Track_more_info")] + partial class Track_more_info + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("AvatarPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FollowersCount") + .HasColumnType("int"); + + b.Property("FollowingCount") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LastSeen") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Content") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LikeCount") + .HasColumnType("int"); + + b.Property("ParentCommentId") + .HasColumnType("int"); + + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ParentCommentId"); + + b.HasIndex("ThreadId"); + + b.HasIndex("UserId"); + + b.ToTable("Comments"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CommentId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.HasKey("UserId", "CommentId"); + + b.HasIndex("CommentId"); + + b.ToTable("CommentLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.Property("FollowerId") + .HasColumnType("int"); + + b.Property("FollowedId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsActive") + .HasColumnType("bit"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.HasKey("FollowerId", "FollowedId"); + + b.HasIndex("FollowedId"); + + b.ToTable("Follows"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("ResourceId") + .HasColumnType("int"); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("isRead") + .HasColumnType("bit"); + + b.Property("jsonContent") + .IsRequired() + .HasColumnType("NVARCHAR"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.Property("SavedThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.HasKey("SavedThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("SavedThreads"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AnswerContent") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)"); + + b.Property("AskedId") + .HasColumnType("int"); + + b.Property("AskerId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("QuestionContent") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("nvarchar(1000)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.Property("isAnonymous") + .HasColumnType("bit"); + + b.HasKey("Id"); + + b.HasIndex("AskedId"); + + b.HasIndex("AskerId"); + + b.ToTable("Thread", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.Property("ThreadId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("int"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.HasKey("ThreadId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("ThreadLikes"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "ParentComment") + .WithMany("Replies") + .HasForeignKey("ParentCommentId") + .OnDelete(DeleteBehavior.NoAction); + + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("Comments") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("Comments") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("ParentComment"); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.CommentLike", b => + { + b.HasOne("AskFm.DAL.Models.Comment", "Comment") + .WithMany("CommentLikes") + .HasForeignKey("CommentId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("CommentLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Comment"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Follow", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Followed") + .WithMany("Followers") + .HasForeignKey("FollowedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Follower") + .WithMany("Following") + .HasForeignKey("FollowerId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Followed"); + + b.Navigation("Follower"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Notification", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("Notifications") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.SavedThreads", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("SavedThreads") + .HasForeignKey("SavedThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("SavedThreads") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asked") + .WithMany("ReceivedThreads") + .HasForeignKey("AskedId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asker") + .WithMany("AskedThreads") + .HasForeignKey("AskerId") + .OnDelete(DeleteBehavior.NoAction); + + b.Navigation("Asked"); + + b.Navigation("Asker"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ThreadLike", b => + { + b.HasOne("AskFm.DAL.Models.Thread", "Thread") + .WithMany("ThreadLikes") + .HasForeignKey("ThreadId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") + .WithMany("ThreadLikes") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + + b.Navigation("Thread"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => + { + b.Navigation("AskedThreads"); + + b.Navigation("CommentLikes"); + + b.Navigation("Comments"); + + b.Navigation("Followers"); + + b.Navigation("Following"); + + b.Navigation("Notifications"); + + b.Navigation("ReceivedThreads"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Navigation("CommentLikes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Navigation("Comments"); + + b.Navigation("SavedThreads"); + + b.Navigation("ThreadLikes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.cs b/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.cs new file mode 100644 index 0000000..28ec5aa --- /dev/null +++ b/AskFm/AskFm.DAL/Migrations/20250812150332_Track_more_info.cs @@ -0,0 +1,264 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace AskFm.DAL.Migrations +{ + /// + public partial class Track_more_info : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "ThreadLikes", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "ThreadLikes", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Thread", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Thread", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "CreatedAt", + table: "SavedThreads", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "SavedThreads", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Notifications", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Notifications", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Follows", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Follows", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Comments", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "Comments", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "CommentLikes", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "CommentLikes", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "AspNetUsers", + type: "BIT", + nullable: false, + defaultValue: false, + oldClrType: typeof(bool), + oldType: "bit"); + + migrationBuilder.AlterColumn( + name: "DeletedAt", + table: "AspNetUsers", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "AspNetUsers", + type: "DATETIME", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "datetime2"); + + migrationBuilder.AddColumn( + name: "UpdatedAt", + table: "AspNetUsers", + type: "DATETIME", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "ThreadLikes"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Thread"); + + migrationBuilder.DropColumn( + name: "CreatedAt", + table: "SavedThreads"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "SavedThreads"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Notifications"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Follows"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "Comments"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "CommentLikes"); + + migrationBuilder.DropColumn( + name: "UpdatedAt", + table: "AspNetUsers"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "ThreadLikes", + type: "datetime", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Thread", + type: "datetime", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Notifications", + type: "datetime", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Follows", + type: "datetime2", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "Comments", + type: "datetime", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "CommentLikes", + type: "datetime", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "IsDeleted", + table: "AspNetUsers", + type: "bit", + nullable: false, + oldClrType: typeof(bool), + oldType: "BIT", + oldDefaultValue: false); + + migrationBuilder.AlterColumn( + name: "DeletedAt", + table: "AspNetUsers", + type: "datetime2", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + + migrationBuilder.AlterColumn( + name: "CreatedAt", + table: "AspNetUsers", + type: "datetime2", + nullable: false, + oldClrType: typeof(DateTime), + oldType: "DATETIME"); + } + } +} diff --git a/AskFm/AskFm.DAL/Migrations/AppDbContextModelSnapshot.cs b/AskFm/AskFm.DAL/Migrations/AppDbContextModelSnapshot.cs index 9b959ec..0d3ad2e 100644 --- a/AskFm/AskFm.DAL/Migrations/AppDbContextModelSnapshot.cs +++ b/AskFm/AskFm.DAL/Migrations/AppDbContextModelSnapshot.cs @@ -22,6 +22,117 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("AvatarPath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Bio") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("FollowersCount") + .HasColumnType("int"); + + b.Property("FollowingCount") + .HasColumnType("int"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("LastSeen") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.HasIndex("UserName") + .IsUnique(); + + b.ToTable("AspNetUsers", (string)null); + }); + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => { b.Property("Id") @@ -36,7 +147,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(1000)"); b.Property("CreatedAt") - .HasColumnType("datetime"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); b.Property("LikeCount") .HasColumnType("int"); @@ -47,6 +166,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("ThreadId") .HasColumnType("int"); + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + b.Property("UserId") .HasColumnType("int"); @@ -70,7 +192,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("CreatedAt") - .HasColumnType("datetime"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); b.HasKey("UserId", "CommentId"); @@ -88,11 +221,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("CreatedAt") - .HasColumnType("datetime2"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); b.Property("IsActive") .HasColumnType("bit"); + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + b.HasKey("FollowerId", "FollowedId"); b.HasIndex("FollowedId"); @@ -109,11 +253,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); b.Property("CreatedAt") - .HasColumnType("datetime"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); b.Property("ResourceId") .HasColumnType("int"); + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + b.Property("UserId") .HasColumnType("int"); @@ -139,6 +294,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("UserId") .HasColumnType("int"); + b.Property("CreatedAt") + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + b.HasKey("SavedThreadId", "UserId"); b.HasIndex("UserId"); @@ -166,7 +335,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("CreatedAt") - .HasColumnType("datetime"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); b.Property("QuestionContent") .IsRequired() @@ -177,6 +354,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired() .HasColumnType("nvarchar(max)"); + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); + b.Property("isAnonymous") .HasColumnType("bit"); @@ -198,7 +378,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("CreatedAt") - .HasColumnType("datetime"); + .HasColumnType("DATETIME"); + + b.Property("DeletedAt") + .HasColumnType("DATETIME"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("BIT") + .HasDefaultValue(false); + + b.Property("UpdatedAt") + .HasColumnType("DATETIME"); b.HasKey("ThreadId", "UserId"); @@ -207,7 +398,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ThreadLikes"); }); - modelBuilder.Entity("AskFm.DAL.Models.User", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -215,67 +406,145 @@ protected override void BuildModel(ModelBuilder modelBuilder) SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - b.Property("AvatarPath") - .IsRequired() + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() .HasColumnType("nvarchar(max)"); - b.Property("Bio") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); - b.Property("CreatedAt") - .HasColumnType("datetime2"); + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); - b.Property("Email") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); + b.HasKey("Id"); - b.Property("FollowersCount") + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("FollowingCount") + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") .HasColumnType("int"); - b.Property("LastSeen") - .HasColumnType("datetime2"); + b.HasKey("Id"); - b.Property("Name") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); + b.HasIndex("RoleId"); - b.Property("Password") - .IsRequired() - .HasMaxLength(225) - .HasColumnType("nvarchar(225)"); + b.ToTable("AspNetRoleClaims", (string)null); + }); - b.Property("Username") - .IsRequired() - .HasColumnType("nvarchar(450)"); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); b.HasKey("Id"); - b.HasIndex("Username") - .IsUnique(); + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); - b.ToTable("Users"); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); }); modelBuilder.Entity("AskFm.DAL.Models.Comment", b => { b.HasOne("AskFm.DAL.Models.Comment", "ParentComment") .WithMany("Replies") - .HasForeignKey("ParentCommentId"); + .HasForeignKey("ParentCommentId") + .OnDelete(DeleteBehavior.NoAction); b.HasOne("AskFm.DAL.Models.Thread", "Thread") .WithMany("Comments") .HasForeignKey("ThreadId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "User") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") .WithMany("Comments") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.NoAction); @@ -295,10 +564,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "User") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") .WithMany("CommentLikes") .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.NoAction) .IsRequired(); b.Navigation("Comment"); @@ -308,13 +577,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("AskFm.DAL.Models.Follow", b => { - b.HasOne("AskFm.DAL.Models.User", "Followed") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Followed") .WithMany("Followers") .HasForeignKey("FollowedId") .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "Follower") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Follower") .WithMany("Following") .HasForeignKey("FollowerId") .OnDelete(DeleteBehavior.NoAction) @@ -327,10 +596,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("AskFm.DAL.Models.Notification", b => { - b.HasOne("AskFm.DAL.Models.User", "User") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") .WithMany("Notifications") .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.NoAction) .IsRequired(); b.Navigation("User"); @@ -344,7 +613,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "User") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") .WithMany("SavedThreads") .HasForeignKey("UserId") .OnDelete(DeleteBehavior.NoAction) @@ -357,15 +626,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("AskFm.DAL.Models.Thread", b => { - b.HasOne("AskFm.DAL.Models.User", "Asked") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asked") .WithMany("ReceivedThreads") .HasForeignKey("AskedId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "Asker") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "Asker") .WithMany("AskedThreads") - .HasForeignKey("AskerId"); + .HasForeignKey("AskerId") + .OnDelete(DeleteBehavior.NoAction); b.Navigation("Asked"); @@ -380,10 +650,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.NoAction) .IsRequired(); - b.HasOne("AskFm.DAL.Models.User", "User") + b.HasOne("AskFm.DAL.Models.ApplicationUser", "User") .WithMany("ThreadLikes") .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) + .OnDelete(DeleteBehavior.NoAction) .IsRequired(); b.Navigation("Thread"); @@ -391,23 +661,58 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("User"); }); - modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.Navigation("CommentLikes"); + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); - b.Navigation("Replies"); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); }); - modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => { - b.Navigation("Comments"); + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); - b.Navigation("SavedThreads"); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.Navigation("ThreadLikes"); + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("AskFm.DAL.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); }); - modelBuilder.Entity("AskFm.DAL.Models.User", b => + modelBuilder.Entity("AskFm.DAL.Models.ApplicationUser", b => { b.Navigation("AskedThreads"); @@ -425,6 +730,22 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("SavedThreads"); + b.Navigation("ThreadLikes"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Comment", b => + { + b.Navigation("CommentLikes"); + + b.Navigation("Replies"); + }); + + modelBuilder.Entity("AskFm.DAL.Models.Thread", b => + { + b.Navigation("Comments"); + + b.Navigation("SavedThreads"); + b.Navigation("ThreadLikes"); }); #pragma warning restore 612, 618 diff --git a/AskFm/AskFm.DAL/Models/User.cs b/AskFm/AskFm.DAL/Models/ApplicationUser.cs similarity index 78% rename from AskFm/AskFm.DAL/Models/User.cs rename to AskFm/AskFm.DAL/Models/ApplicationUser.cs index 26ebe03..f45c39f 100644 --- a/AskFm/AskFm.DAL/Models/User.cs +++ b/AskFm/AskFm.DAL/Models/ApplicationUser.cs @@ -1,19 +1,18 @@ +using System.Runtime.InteropServices.JavaScript; +using Microsoft.AspNetCore.Identity; + namespace AskFm.DAL.Models; -public class User +public class ApplicationUser : IdentityUser, ITrackable { - public int Id { get; set; } public string Name { get; set; } - public string Username { get; set; } public string Email { get; set; } - public string Password { get; set; } public string Bio { get; set; } public string AvatarPath { get; set; } public int FollowersCount { get; set; } public int FollowingCount { get; set; } - public DateTime CreatedAt { get; set; } public DateTime LastSeen { get; set; } public virtual ICollection? AskedThreads { get; set; } @@ -25,5 +24,9 @@ public class User public virtual ICollection? CommentLikes { get; set; } public virtual ICollection? Notifications { get; set; } public virtual ICollection? SavedThreads { get; set; } - + + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/Comment.cs b/AskFm/AskFm.DAL/Models/Comment.cs index b4576ba..b936b24 100644 --- a/AskFm/AskFm.DAL/Models/Comment.cs +++ b/AskFm/AskFm.DAL/Models/Comment.cs @@ -1,14 +1,16 @@ +using System.Runtime.InteropServices.JavaScript; +using Microsoft.AspNetCore.Identity; + namespace AskFm.DAL.Models; -public class Comment +public class Comment : ITrackable { public int Id { get; set; } public string Content { get; set; } - public DateTime CreatedAt { get; set; } public int LikeCount { get; set; } public int? UserId { get; set; } - public virtual User? User { get; set; } + public virtual ApplicationUser? User { get; set; } public int ThreadId { get; set; } public virtual Thread? Thread { get; set; } @@ -18,4 +20,8 @@ public class Comment public virtual ICollection? Replies { get; set; } public virtual ICollection? CommentLikes { get; set; } + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/CommentLike.cs b/AskFm/AskFm.DAL/Models/CommentLike.cs index 1bc9030..b75e030 100644 --- a/AskFm/AskFm.DAL/Models/CommentLike.cs +++ b/AskFm/AskFm.DAL/Models/CommentLike.cs @@ -1,10 +1,15 @@ +using System.Runtime.InteropServices.JavaScript; + namespace AskFm.DAL.Models; -public class CommentLike +public class CommentLike : ITrackable { public int CommentId { get; set; } public virtual Comment? Comment { get; set; } public int UserId { get; set; } - public virtual User? User { get; set; } + public virtual ApplicationUser? User { get; set; } + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/Follow.cs b/AskFm/AskFm.DAL/Models/Follow.cs index 639b05c..1c41965 100644 --- a/AskFm/AskFm.DAL/Models/Follow.cs +++ b/AskFm/AskFm.DAL/Models/Follow.cs @@ -1,14 +1,21 @@ +using System.Runtime.InteropServices.JavaScript; + namespace AskFm.DAL.Models; -public class Follow +public class Follow : ITrackable { public int FollowerId { get; set; } - public virtual User? Follower { get; set; } + public virtual ApplicationUser? Follower { get; set; } public int FollowedId { get; set; } - public virtual User? Followed { get; set; } - public DateTime CreatedAt { get; set; } + public virtual ApplicationUser? Followed { get; set; } // is this follow available public bool IsActive { get; set; } = true; + + + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/ITrackable.cs b/AskFm/AskFm.DAL/Models/ITrackable.cs new file mode 100644 index 0000000..ec0dd36 --- /dev/null +++ b/AskFm/AskFm.DAL/Models/ITrackable.cs @@ -0,0 +1,11 @@ +using System.Runtime.InteropServices.JavaScript; + +namespace AskFm.DAL.Models; + +public interface ITrackable +{ + bool IsDeleted { get; set; } + DateTime DeletedAt { get; set; } + DateTime UpdatedAt { get; set; } + DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/Notification.cs b/AskFm/AskFm.DAL/Models/Notification.cs index 5e1cedf..0ea01ef 100644 --- a/AskFm/AskFm.DAL/Models/Notification.cs +++ b/AskFm/AskFm.DAL/Models/Notification.cs @@ -1,14 +1,20 @@ +using System.Runtime.InteropServices.JavaScript; + namespace AskFm.DAL.Models; -public class Notification +public class Notification : ITrackable { public GCNotificationStatus Type; public int Id { get; set; } public int UserId { get; set; } - public virtual User? User { get; set; } + public virtual ApplicationUser? User { get; set; } public bool isRead { get; set; } public int ResourceId { get; set; } public string jsonContent { get; set; } + + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/SavedThreads.cs b/AskFm/AskFm.DAL/Models/SavedThreads.cs index 01189aa..d856d68 100644 --- a/AskFm/AskFm.DAL/Models/SavedThreads.cs +++ b/AskFm/AskFm.DAL/Models/SavedThreads.cs @@ -1,10 +1,16 @@ +using System.Runtime.InteropServices.JavaScript; + namespace AskFm.DAL.Models; -public class SavedThreads +public class SavedThreads : ITrackable { public int SavedThreadId { get; set; } public int UserId { get; set; } public virtual Thread? Thread { get; set; } - public virtual User? User { get; set; } + public virtual ApplicationUser? User { get; set; } + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/Thread.cs b/AskFm/AskFm.DAL/Models/Thread.cs index 019f533..949b163 100644 --- a/AskFm/AskFm.DAL/Models/Thread.cs +++ b/AskFm/AskFm.DAL/Models/Thread.cs @@ -1,7 +1,8 @@ +using System.Runtime.InteropServices.JavaScript; using AskFm.DAL.Enums; namespace AskFm.DAL.Models; -public class Thread +public class Thread : ITrackable { public int Id { get; set; } public string QuestionContent { get; set; } @@ -9,14 +10,17 @@ public class Thread public ThreadStatus Status { get; set; } public bool isAnonymous { get; set; } - public DateTime CreatedAt { get; set; } public int? AskerId { get; set; } - public virtual User? Asker { get; set; } + public virtual ApplicationUser? Asker { get; set; } public int AskedId { get; set; } - public virtual User? Asked { get; set; } + public virtual ApplicationUser? Asked { get; set; } public virtual ICollection? Comments { get; set; } public virtual ICollection? ThreadLikes { get; set; } public virtual ICollection? SavedThreads { get; set; } + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/Models/ThreadLike.cs b/AskFm/AskFm.DAL/Models/ThreadLike.cs index cbf62c7..a1ad625 100644 --- a/AskFm/AskFm.DAL/Models/ThreadLike.cs +++ b/AskFm/AskFm.DAL/Models/ThreadLike.cs @@ -1,12 +1,17 @@ +using System.Runtime.InteropServices.JavaScript; + namespace AskFm.DAL.Models; -public class ThreadLike +public class ThreadLike : ITrackable { public int ThreadId { get; set; } public virtual Thread? Thread { get; set; } public int UserId { get; set; } - public virtual User? User { get; set; } + public virtual ApplicationUser? User { get; set; } + public bool IsDeleted { get; set; } + public DateTime DeletedAt { get; set; } + public DateTime UpdatedAt { get; set; } public DateTime CreatedAt { get; set; } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/UserConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/ApplicationUserConfigration.cs similarity index 60% rename from AskFm/AskFm.DAL/ModelsConfigrations/UserConfigration.cs rename to AskFm/AskFm.DAL/ModelsConfigrations/ApplicationUserConfigration.cs index b549241..27b5010 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/UserConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/ApplicationUserConfigration.cs @@ -3,12 +3,12 @@ namespace AskFm.DAL.Models; -public class UserConfigration : IEntityTypeConfiguration +public class ApplicationUserConfigration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public void Configure(EntityTypeBuilder builder) { builder.HasKey(x => x.Id); - builder.HasIndex(u => u.Username).IsUnique(); + builder.HasIndex(u => u.UserName).IsUnique(); builder.Property(u => u.Name) .HasMaxLength(50) @@ -17,10 +17,9 @@ public void Configure(EntityTypeBuilder builder) builder.Property(u => u.Bio) .HasMaxLength(500); - builder.Property(x => x.Username).IsRequired(); + builder.Property(x => x.UserName).IsRequired(); - builder.Property(x => x.Password) - .HasMaxLength(225) + builder.Property(x => x.PasswordHash) .IsRequired(); builder.Property(x => x.Email) diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/CommentConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/CommentConfigration.cs index 0bc7fd6..a02f7ef 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/CommentConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/CommentConfigration.cs @@ -14,20 +14,16 @@ public void Configure(EntityTypeBuilder builder) .IsRequired() .HasMaxLength(1000); - builder.Property(c => c.CreatedAt) - .HasColumnType("datetime") - .IsRequired(); - builder.HasOne(c => c.Thread) .WithMany(t => t.Comments) .HasForeignKey(c => c.ThreadId) - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.NoAction); builder.HasOne(c => c.ParentComment) .WithMany(c => c.Replies) .HasForeignKey(c => c.ParentCommentId) - .OnDelete(DeleteBehavior.ClientSetNull); + .OnDelete(DeleteBehavior.NoAction); builder.HasOne(c => c.User) diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/CommentLikeConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/CommentLikeConfigration.cs index a7e29dc..b8b8e9d 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/CommentLikeConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/CommentLikeConfigration.cs @@ -9,15 +9,11 @@ public class CommentLikeConfigration : IEntityTypeConfiguration public void Configure(EntityTypeBuilder builder) { builder.HasKey(cl => new { cl.UserId, cl.CommentId }); - - builder.Property(cl => cl.CreatedAt) - .HasColumnType("datetime") - .IsRequired(); - + builder.HasOne(cl => cl.User) .WithMany(u => u.CommentLikes) .HasForeignKey(cl => cl.UserId) - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.NoAction); builder.HasOne(cl => cl.Comment) .WithMany(c => c.CommentLikes) diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/NotificationConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/NotificationConfigration.cs index 4c11b35..afeda9b 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/NotificationConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/NotificationConfigration.cs @@ -15,14 +15,11 @@ public void Configure(EntityTypeBuilder builder) builder.Property(n => n.isRead) .IsRequired(); - - builder.Property(n => n.CreatedAt) - .HasColumnType("datetime") - .IsRequired(); + builder.HasOne(n => n.User) .WithMany(u => u.Notifications) .HasForeignKey(n => n.UserId) - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.NoAction); } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/ThreadConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/ThreadConfigration.cs index 0f9cdb8..10cf68a 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/ThreadConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/ThreadConfigration.cs @@ -19,9 +19,6 @@ public void Configure(EntityTypeBuilder builder) builder.Property(t => t.AnswerContent) .HasMaxLength(4000); - builder.Property(t => t.CreatedAt) - .HasColumnType("datetime") - .IsRequired(); builder.Property(t => t.isAnonymous) .IsRequired(); @@ -32,12 +29,12 @@ public void Configure(EntityTypeBuilder builder) builder.HasOne(t => t.Asked) .WithMany(u => u.ReceivedThreads) .HasForeignKey(t => t.AskedId) - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.NoAction); builder.HasOne(t => t.Asker) .WithMany(u => u.AskedThreads) .HasForeignKey(t => t.AskerId) - .OnDelete(DeleteBehavior.ClientSetNull); + .OnDelete(DeleteBehavior.NoAction); diff --git a/AskFm/AskFm.DAL/ModelsConfigrations/ThreadLikeConfigration.cs b/AskFm/AskFm.DAL/ModelsConfigrations/ThreadLikeConfigration.cs index a1ef8f6..1c6e96c 100644 --- a/AskFm/AskFm.DAL/ModelsConfigrations/ThreadLikeConfigration.cs +++ b/AskFm/AskFm.DAL/ModelsConfigrations/ThreadLikeConfigration.cs @@ -9,15 +9,11 @@ public class ThreadLikeConfigration : IEntityTypeConfiguration public void Configure(EntityTypeBuilder builder) { builder.HasKey(tl => new { tl.ThreadId, tl.UserId }); - - builder.Property(ql => ql.CreatedAt) - .HasColumnType("datetime") - .IsRequired(); - + builder.HasOne(tl => tl.User) .WithMany(u => u.ThreadLikes) .HasForeignKey(tl => tl.UserId) - .OnDelete(DeleteBehavior.Cascade); + .OnDelete(DeleteBehavior.NoAction); builder.HasOne(tl => tl.Thread) .WithMany(t => t.ThreadLikes) diff --git a/AskFm/AskFm.DAL/Repositories/UserRepository.cs b/AskFm/AskFm.DAL/Repositories/UserRepository.cs index 00d5af1..dcf55f3 100644 --- a/AskFm/AskFm.DAL/Repositories/UserRepository.cs +++ b/AskFm/AskFm.DAL/Repositories/UserRepository.cs @@ -4,16 +4,16 @@ namespace AskFm.DAL.Repositories; -public class UserRepository : Repository, IUserRepository +public class UserRepository : Repository, IApplicationUserRepository { public UserRepository(AppDbContext context) : base(context) { } - public async Task GetByUsernameAsync(string username) + public async Task GetByUsernameAsync(string username) { return await _context.Users - .FirstOrDefaultAsync(u => u.Username == username); + .FirstOrDefaultAsync(u => u.UserName == username); } } \ No newline at end of file diff --git a/AskFm/AskFm.DAL/UnitOfWork.cs b/AskFm/AskFm.DAL/UnitOfWork.cs index a38bf14..573f3ae 100644 --- a/AskFm/AskFm.DAL/UnitOfWork.cs +++ b/AskFm/AskFm.DAL/UnitOfWork.cs @@ -9,7 +9,7 @@ public class UnitOfWork : IUnitOfWork { private readonly AppDbContext _context; - private IRepository _users; + private IRepository _users; private IRepository _threads; private IRepository _savedThreads; private IRepository _threadLikes; @@ -24,13 +24,13 @@ public UnitOfWork(AppDbContext context) { _context = context; } - public IRepository Users + public IRepository Users { get { if (_users == null) { - _users = new Repository(_context); + _users = new Repository(_context); } return _users; }