From f61809ca0328627b7ababea0353652f63e0f3a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:09:51 -0800 Subject: [PATCH 01/44] add AuthorData.xlsx to SeedData Foulder --- Refhub/Data/SeedData/AuthorData.xlsx | Bin 0 -> 4882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/Data/SeedData/AuthorData.xlsx diff --git a/Refhub/Data/SeedData/AuthorData.xlsx b/Refhub/Data/SeedData/AuthorData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..19fc1e27c2677d2cc3574ad0605b4d2a764fd47a GIT binary patch literal 4882 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 AG5`Po literal 0 HcmV?d00001 From fd281fe821c81f5a548adc668f1f39eb64149cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:12:30 -0800 Subject: [PATCH 02/44] Move Seed Data foulder to main root project --- Refhub/SeedData/AuthorData.xlsx | Bin 0 -> 4882 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/AuthorData.xlsx diff --git a/Refhub/SeedData/AuthorData.xlsx b/Refhub/SeedData/AuthorData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..19fc1e27c2677d2cc3574ad0605b4d2a764fd47a GIT binary patch literal 4882 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 AG5`Po literal 0 HcmV?d00001 From 6d569728408f7bd27c58cc2e74d178fe89e30a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:13:45 -0800 Subject: [PATCH 03/44] create foulder to write class --- Refhub/Data/SeedData/AuthorData.xlsx | Bin 4882 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Refhub/Data/SeedData/AuthorData.xlsx diff --git a/Refhub/Data/SeedData/AuthorData.xlsx b/Refhub/Data/SeedData/AuthorData.xlsx deleted file mode 100644 index 19fc1e27c2677d2cc3574ad0605b4d2a764fd47a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4882 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 AG5`Po From 83e769d25618b1192a586483634402c8124d1b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:14:48 -0800 Subject: [PATCH 04/44] create ExcelSeeder class --- Refhub/Data/Seed/ExcelSeeder.cs | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Refhub/Data/Seed/ExcelSeeder.cs diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs new file mode 100644 index 00000000..0bf64746 --- /dev/null +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -0,0 +1,6 @@ +namespace Refhub.Data.Seed +{ + public class ExcelSeeder + { + } +} From 149842046d2bf888f97b9a49ea21c1d27850f8d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:35:33 -0800 Subject: [PATCH 05/44] design and write ExcelSeeder class --- Refhub/Data/Seed/ExcelSeeder.cs | 36 +++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index 0bf64746..099c6849 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -1,6 +1,38 @@ -namespace Refhub.Data.Seed +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Refhub.Data.Models; +using OfficeOpenXml; +using Microsoft.EntityFrameworkCore.Metadata.Conventions; + +namespace Refhub.Data.Seed { - public class ExcelSeeder + public static class ExcelSeeder { + public static List ReadAuthorsFromExcel(string filePath) + { + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + var authors = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var worksheet = package.Workbook.Worksheets[0]; + int rowCount = worksheet.Dimension.Rows; + + for (int row = 2; row <= rowCount; row++) + { + var fullName = worksheet.Cells[row, 1].Text; + var slug = worksheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(fullName) && !String.IsNullOrWhiteSpace(slug)) + { + authors.Add(new Author + { + FullName = fullName, + Slug = slug + }); + } + } + return authors; + } + } } } From 4b662012e2652495da6c925da0ed639be987fca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:46:10 -0800 Subject: [PATCH 06/44] create and design Seed Data Configuration in Program File --- Refhub/Program.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Refhub/Program.cs b/Refhub/Program.cs index f8b99052..81bbf07d 100644 --- a/Refhub/Program.cs +++ b/Refhub/Program.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Refhub.Data.Context; +using Refhub.Data.Seed; using Refhub.Tools.ExtentionMethod; @@ -65,6 +66,22 @@ public static void Main(string[] args) app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); + + // Seed Data Configuration + var filePath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); + var authors = ExcelSeeder.ReadAuthorsFromExcel(filePath); + + using (var scope = app.Services.CreateScope()) + { + var db = scope.ServiceProvider.GetRequiredService(); + + if (!db.Authors.Any()) + { + db.Authors.AddRange(authors); + db.SaveChanges(); + } + } + app.Run(); } } From e2a776b0a444179b204519f3698384b2f0d4844c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 06:47:43 -0800 Subject: [PATCH 07/44] Apply changes --- Refhub/Refhub.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Refhub/Refhub.csproj b/Refhub/Refhub.csproj index 91b998eb..f04d5c26 100644 --- a/Refhub/Refhub.csproj +++ b/Refhub/Refhub.csproj @@ -12,6 +12,7 @@ + From 9841b43a1a849e6c7babf0bed000f0a4499728bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 10:44:20 -0800 Subject: [PATCH 08/44] add migration --- .../20250616145440_AddAuthorTable.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Refhub/Migrations/20250616145440_AddAuthorTable.cs diff --git a/Refhub/Migrations/20250616145440_AddAuthorTable.cs b/Refhub/Migrations/20250616145440_AddAuthorTable.cs new file mode 100644 index 00000000..d4e157b5 --- /dev/null +++ b/Refhub/Migrations/20250616145440_AddAuthorTable.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Refhub.Migrations +{ + /// + public partial class AddAuthorTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Slug", + table: "Books", + type: "nvarchar(450)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(max)"); + + migrationBuilder.CreateIndex( + name: "IX_Books_Slug", + table: "Books", + column: "Slug", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Books_Slug", + table: "Books"); + + migrationBuilder.AlterColumn( + name: "Slug", + table: "Books", + type: "nvarchar(max)", + nullable: false, + oldClrType: typeof(string), + oldType: "nvarchar(450)"); + } + } +} From 6cfaa95ddab5410496e2f5ff08bf9881cebb4d13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 10:44:34 -0800 Subject: [PATCH 09/44] add migration --- .../20250616145440_AddAuthorTable.Designer.cs | 541 ++++++++++++++++++ 1 file changed, 541 insertions(+) create mode 100644 Refhub/Migrations/20250616145440_AddAuthorTable.Designer.cs diff --git a/Refhub/Migrations/20250616145440_AddAuthorTable.Designer.cs b/Refhub/Migrations/20250616145440_AddAuthorTable.Designer.cs new file mode 100644 index 00000000..fe75f4b8 --- /dev/null +++ b/Refhub/Migrations/20250616145440_AddAuthorTable.Designer.cs @@ -0,0 +1,541 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Refhub.Data.Context; + +#nullable disable + +namespace Refhub.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20250616145440_AddAuthorTable")] + partial class AddAuthorTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + 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") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + 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") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + 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") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + 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("Refhub.Data.Models.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .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") + .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.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Refhub.Data.Models.Author", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("FullName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Authors"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Book", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("CategoryId") + .HasColumnType("int"); + + b.Property("FilePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("ImagePath") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("PageCount") + .HasColumnType("int"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(155) + .HasColumnType("nvarchar(155)"); + + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.HasIndex("Slug") + .IsUnique(); + + b.HasIndex("UserId"); + + b.ToTable("Books"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookAuthor", b => + { + b.Property("BookId") + .HasColumnType("int"); + + b.Property("AuthorId") + .HasColumnType("int"); + + b.HasKey("BookId", "AuthorId"); + + b.HasIndex("AuthorId"); + + b.ToTable("BookAuthors"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookKeyword", b => + { + b.Property("BookId") + .HasColumnType("int"); + + b.Property("KeywordId") + .HasColumnType("int"); + + b.HasKey("BookId", "KeywordId"); + + b.HasIndex("KeywordId"); + + b.ToTable("BookKeywords"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookRelation", b => + { + b.Property("BookId") + .HasColumnType("int"); + + b.Property("RelatedBookId") + .HasColumnType("int"); + + b.HasKey("BookId", "RelatedBookId"); + + b.HasIndex("RelatedBookId"); + + b.ToTable("BookRelations"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("slug") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Keyword", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("Word") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.ToTable("Keywords"); + }); + + 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("Refhub.Data.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Refhub.Data.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("Refhub.Data.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Refhub.Data.Models.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Refhub.Data.Models.Book", b => + { + b.HasOne("Refhub.Data.Models.Category", "Category") + .WithMany("Books") + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Refhub.Data.Models.ApplicationUser", "User") + .WithMany("Books") + .HasForeignKey("UserId"); + + b.Navigation("Category"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookAuthor", b => + { + b.HasOne("Refhub.Data.Models.Author", "Author") + .WithMany("BookAuthors") + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Refhub.Data.Models.Book", "Book") + .WithMany("BookAuthors") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + + b.Navigation("Book"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookKeyword", b => + { + b.HasOne("Refhub.Data.Models.Book", "Book") + .WithMany("BookKeywords") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Refhub.Data.Models.Keyword", "Keyword") + .WithMany("BookKeywords") + .HasForeignKey("KeywordId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("Keyword"); + }); + + modelBuilder.Entity("Refhub.Data.Models.BookRelation", b => + { + b.HasOne("Refhub.Data.Models.Book", "Book") + .WithMany("RelatedTo") + .HasForeignKey("BookId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Refhub.Data.Models.Book", "RelatedBook") + .WithMany("RelatedFrom") + .HasForeignKey("RelatedBookId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Book"); + + b.Navigation("RelatedBook"); + }); + + modelBuilder.Entity("Refhub.Data.Models.ApplicationUser", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Author", b => + { + b.Navigation("BookAuthors"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Book", b => + { + b.Navigation("BookAuthors"); + + b.Navigation("BookKeywords"); + + b.Navigation("RelatedFrom"); + + b.Navigation("RelatedTo"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Category", b => + { + b.Navigation("Books"); + }); + + modelBuilder.Entity("Refhub.Data.Models.Keyword", b => + { + b.Navigation("BookKeywords"); + }); +#pragma warning restore 612, 618 + } + } +} From d2959721375444243d8f7e3e0b3aa8714f74b3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 10:44:59 -0800 Subject: [PATCH 10/44] snapahot updated --- Refhub/Migrations/AppDbContextModelSnapshot.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Refhub/Migrations/AppDbContextModelSnapshot.cs b/Refhub/Migrations/AppDbContextModelSnapshot.cs index 761c8139..e742b1fc 100644 --- a/Refhub/Migrations/AppDbContextModelSnapshot.cs +++ b/Refhub/Migrations/AppDbContextModelSnapshot.cs @@ -17,7 +17,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.15") + .HasAnnotation("ProductVersion", "9.0.5") .HasAnnotation("Relational:MaxIdentifierLength", 128); SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); @@ -266,7 +266,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Slug") .IsRequired() - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(450)"); b.Property("Title") .IsRequired() @@ -280,6 +280,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("CategoryId"); + b.HasIndex("Slug") + .IsUnique(); + b.HasIndex("UserId"); b.ToTable("Books"); From a57a48eb84e56a24287aa563006bc2187106a9f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 10:45:10 -0800 Subject: [PATCH 11/44] apply changes --- Refhub/Refhub.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Refhub/Refhub.csproj b/Refhub/Refhub.csproj index f04d5c26..91b998eb 100644 --- a/Refhub/Refhub.csproj +++ b/Refhub/Refhub.csproj @@ -12,7 +12,6 @@ - From cba8dab408850b688e0f2b36fc98698cb9f1b988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:04:50 -0800 Subject: [PATCH 12/44] apply changes and install Package EPPlus version 5.8.3 --- Refhub/Refhub.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Refhub/Refhub.csproj b/Refhub/Refhub.csproj index 91b998eb..09831fcc 100644 --- a/Refhub/Refhub.csproj +++ b/Refhub/Refhub.csproj @@ -12,6 +12,7 @@ + From fcff217885c0d5d6fb7b3c92088a0f37146829bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:28:50 -0800 Subject: [PATCH 13/44] Add Book Data Excel file --- Refhub/SeedData/BookData.xlsx | Bin 0 -> 5816 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/BookData.xlsx diff --git a/Refhub/SeedData/BookData.xlsx b/Refhub/SeedData/BookData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..390ca1feb749aa068a3c64be492384916323d905 GIT binary patch literal 5816 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 Date: Mon, 16 Jun 2025 23:29:56 -0800 Subject: [PATCH 14/44] add comment to ReadAuthorsFromExcel Method --- Refhub/Data/Seed/ExcelSeeder.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index 099c6849..bb731ef5 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -7,6 +7,7 @@ namespace Refhub.Data.Seed { public static class ExcelSeeder { + // Read Data from Author File public static List ReadAuthorsFromExcel(string filePath) { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; From 337fd87898fbabd560e36af5664f634949c5a4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:30:56 -0800 Subject: [PATCH 15/44] add comment to ReadBooksFromExcel Method --- Refhub/Data/Seed/ExcelSeeder.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index bb731ef5..37383892 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -35,5 +35,7 @@ public static List ReadAuthorsFromExcel(string filePath) return authors; } } + + // Read Data from Book File } } From 7716ece9b7b3f7ef5e02ddbe1e763945fd2564e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:40:37 -0800 Subject: [PATCH 16/44] create ReadBooksFromExcel Method --- Refhub/Data/Seed/ExcelSeeder.cs | 48 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index 37383892..babe87b5 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -15,13 +15,13 @@ public static List ReadAuthorsFromExcel(string filePath) using (var package = new ExcelPackage(new FileInfo(filePath))) { - var worksheet = package.Workbook.Worksheets[0]; - int rowCount = worksheet.Dimension.Rows; + var workSheet = package.Workbook.workSheets[0]; + int rowCount = workSheet.Dimension.Rows; for (int row = 2; row <= rowCount; row++) { - var fullName = worksheet.Cells[row, 1].Text; - var slug = worksheet.Cells[row, 2].Text; + var fullName = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; if (!String.IsNullOrWhiteSpace(fullName) && !String.IsNullOrWhiteSpace(slug)) { @@ -37,5 +37,45 @@ public static List ReadAuthorsFromExcel(string filePath) } // Read Data from Book File + public static List ReadBooksFromExcel(string filePath) + { + ExcelPackage.LicenseContext= LicenseContext.NonCommercial; + var books = new List(); + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + + for(int row = 2; row <= rowCount; row++) + { + var title = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; + var pageCountText = workSheet.Cells[row, 3].Text; + var filePathCell = workSheet.Cells[row, 4].Text; + var imagePath = workSheet.Cells[row, 5].Text; + var categoryIdText = workSheet.Cells[row, 6].Text; + var userId = workSheet.Cells[row, 7].Text; + + + if (string.IsNullOrWhiteSpace(title) || string.IsNullOrWhiteSpace(slug)) + continue; + + int.TryParse(pageCountText, out int pageCount); + int.TryParse(categoryIdText, out int categoryId); + + books.Add(new Book + { + Title = title, + Slug = slug, + PageCount = pageCount, + FilePath = filePathCell, + ImagePath = imagePath, + CategoryId = categoryId, + UserId = string.IsNullOrWhiteSpace(userId) ? null : userId + }); + } + } + return books; + } } } From d8554b07dc0e4b07f3adba1b679d64c7e4acf8cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:50:31 -0800 Subject: [PATCH 17/44] This class is designed to separate configurations in the program. --- Refhub/Data/Seed/SeedInitialData.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Refhub/Data/Seed/SeedInitialData.cs diff --git a/Refhub/Data/Seed/SeedInitialData.cs b/Refhub/Data/Seed/SeedInitialData.cs new file mode 100644 index 00000000..abd2f8df --- /dev/null +++ b/Refhub/Data/Seed/SeedInitialData.cs @@ -0,0 +1,7 @@ +namespace Refhub.Data.Seed +{ + public class SeedInitialData + { + + } +} From ef522fbd7187ec623ff560507860f981166029fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Mon, 16 Jun 2025 23:52:05 -0800 Subject: [PATCH 18/44] Rename --- Refhub/Data/Seed/SeedInitialData.cs | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 Refhub/Data/Seed/SeedInitialData.cs diff --git a/Refhub/Data/Seed/SeedInitialData.cs b/Refhub/Data/Seed/SeedInitialData.cs deleted file mode 100644 index abd2f8df..00000000 --- a/Refhub/Data/Seed/SeedInitialData.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Refhub.Data.Seed -{ - public class SeedInitialData - { - - } -} From a83d0e83e6e8ae38e01f9f17f7787da2fc747864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Tue, 17 Jun 2025 00:02:43 -0800 Subject: [PATCH 19/44] Rename class --- Refhub/Data/Seed/DataSeeder.cs | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Refhub/Data/Seed/DataSeeder.cs diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs new file mode 100644 index 00000000..989a07a9 --- /dev/null +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -0,0 +1,7 @@ +namespace Refhub.Data.Seed +{ + public class DataSeeder + { + + } +} From 6f4a07cb3131a5dd3ae9547a9a0bbffd67322ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Tue, 17 Jun 2025 00:05:49 -0800 Subject: [PATCH 20/44] add Authors and Books Configuration --- Refhub/Data/Seed/DataSeeder.cs | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 989a07a9..6f434780 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -1,7 +1,34 @@ -namespace Refhub.Data.Seed +using Microsoft.EntityFrameworkCore; +using Refhub.Data.Context; + +namespace Refhub.Data.Seed { - public class DataSeeder + public static class DataSeeder { + public static void SeedInitialData(IServiceProvider serviceProvider) + { + using var scope = serviceProvider.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); + + db.Database.Migrate(); + + // Authors + if (!db.Authors.Any()) + { + var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); + var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); + db.Authors.AddRange(authors); + } + + // Books + if (!db.Books.Any()) + { + var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); + var books = ExcelSeeder.ReadBooksFromExcel(bookPath); + db.Books.AddRange(books); + } + db.SaveChanges(); + } } } From 4383c6a89e6c28a4ac39ade7a0df4530396672c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Tue, 17 Jun 2025 00:07:24 -0800 Subject: [PATCH 21/44] add SeedInitialData to Program --- Refhub/Program.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/Refhub/Program.cs b/Refhub/Program.cs index 81bbf07d..e7e33ce1 100644 --- a/Refhub/Program.cs +++ b/Refhub/Program.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Refhub.Data.Context; +using Refhub.Data.Models; using Refhub.Data.Seed; using Refhub.Tools.ExtentionMethod; @@ -67,20 +68,8 @@ public static void Main(string[] args) name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); - // Seed Data Configuration - var filePath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); - var authors = ExcelSeeder.ReadAuthorsFromExcel(filePath); - - using (var scope = app.Services.CreateScope()) - { - var db = scope.ServiceProvider.GetRequiredService(); - - if (!db.Authors.Any()) - { - db.Authors.AddRange(authors); - db.SaveChanges(); - } - } + // Seed initial data from Excel files + DataSeeder.SeedInitialData(app.Services); app.Run(); } From 05419781cee3de25426645657c214cfdf38f133e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Tue, 17 Jun 2025 03:59:48 -0800 Subject: [PATCH 22/44] add AuthorBook Data in excel file --- Refhub/SeedData/AuthorBookData.xlsx | Bin 0 -> 4771 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/AuthorBookData.xlsx diff --git a/Refhub/SeedData/AuthorBookData.xlsx b/Refhub/SeedData/AuthorBookData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a4512992574ebcc587c71b8dad99ae69f0cd9f18 GIT binary patch literal 4771 zcmai21zgkX8U{v6Ga9MG=$2H0DJ3C|0+Wy&qXm@CjSgWTjS5IfD2$LUX#_-(hDl3` z2nYh+4evd2y!V{@uKxS|_C4G8eDC|b&pTaB06r}aF)=ZY1kYOt&beU3Tzfl-+PGVK z!Caso|G5ws@pg8~9yW7n7b7G34BVi&H4B3<0+ndZhqc8h(A+L8i4XfI@}>jdYDmNU zaM_&u!H3&#Ts&*ODO&;kxz;La2z=?PcFedawp~$=_+&%J?!voOO%pm@zE?3xl?^o( z{;}z2URX&T5ZeLKxGjGLeTi)KT^0EvM*;FmG0C9%gWH28Ybsx^5oh?le)WWBeyt6V z0a(~Q)fz+8NL@I%o_+C1mJ>m5bwqGrhb}E9D%X?OJ;v<{3YCb)i;zwcc(u+yp{95u zM9(J9^mL+Io73p1u5}GI_=& zON=V)$u_0&Em6+Y zWT{G7K*0Ng+yU{$_KF^Ua3T8SVD}@1tOnQPJPkKwD2pDN^LvV?qPd}ZDuQzRlAA7P`GSt6%&OEdIKPUNj&FdJ77)zV$iYj;W|T7u3+b#yp&`He^r z-AGrn0IW;_wo%_M9-Xh7J1j!)^am3WBT|qDp3@M<8GayZrDmRSbT^^;-p+Nw=dN(k z7?{DZ8kw=)^$~6Q3z0iPWqmIUi1JVN{(PJ>u3-S1XfbQv@(EgO-IC5Me zHXsqEQfYIoxlf2XuAGne#fTocL`RD}Qp1y9Eaob~>}uWn0317#s{0)uDY>&Vva+($6b>r7`(LAPo=okj28~!ZxzE(F#;8Q2>fuP&t zJ-Z2l4I9hCbUD+uWs@LMdSm04oa~mnPA>^ag@vZSB~a75kXho!2nkKD%D3mnamI?t z`h7Ib9X!@#WimjSf8jm|Cr7mmZLnigCfKx2eG`*1p#=YwGF(5a?_A1QxZ66NPaF~K z`?w*^3+-Z5glM35gqUB_hpr38v4 zO!l&1&LV+WW#6Y>3Yx*0drbg(AS4cj0$Jt|Yc)OBmbC7ZxtHZ{!&ITyo`#$wr5;ry zzOUfC?_Mf4sJ%RyPux)utvLjepAe_uAhpB#AF+dA8do;{yc z%p0RAmuU{Flh9MZd{f(46MutVW#%n*$gQ=SHHnIy{I+pCY1nBqqo1?CX09EVtp(nK zM1+JyYeIiX3ljk)B1RJGXm4RmMMb}8**7nByyx-52R9@kEi7$0w)7*A`m@9CCz=;F zikI+`uL1=d!=sWrFK|-xNzgO+Tu(cqUy|$4*Yb%~jAy5FR!y`vkx2fS+&1~7r3?Hp zSCXSaPSy_58;t-)=OaasRa8`BS^RMk2r7Q`GU!VRazrUPJot;!(?^sqKQ@`2Qp+_@ z=~J+YnJH=h;FvVcCA_voRXf(gYy@ccTj5qHoM)N$^=A%-UsDk`o${bRoh_*#EMlgp zbA2H{ws+MVKF8`%S2qDM3#{$*12nFiiTc;V4@T2(0E9Ix^A~W- zn^ViVP`*xM-HSveH@y=O7QX}-wS>+TwXAa$=f&%5P=1L*zEISpxvbUEbZIT>fdkSM zdb`j<3<1MiMX_}u%=uX3u z%!5aYCMM9`{RHW+zVxI9!7tP;MB9x^1>0Gv#l0+e+iM2%tuE(US%M4km~QD25uhs_ zznSL~N8%XJq}+dgtTQU_mtTmSAfI9)as8BCHo{8X^3UbkWJ3GZ0}XR2 z)xQyMttS3x70^4K76CFAC`wO|8MruYNyjv;KUaw65|uj%&QS?nkGC>krZauWa#{5v z1O^t6OlfcM4vH`TUTLsBl4Z}a+k0o@B%?8>kJV`D;q3kXus#1&Z$BlmXTn|ibqgZ} zzTHgh_+9R(sK(1lqyE-1tJ@HpM!~((1D&bf%0nV-q1onzSn^?dQyIlS6&mf&Li4b< zbhouJ@N~!adu*H6iocFk7Zn{eYx{=OXjmkOnhyWKH+VQ+dVJvhfZ^Bu+sbZ-vny?0 znb55PKn#e7a@T}_uy~p0?P$lLXIgn{q^g5eH-gQa?UIVp3j@{so^Ge}!TkI;n8)8M3HiS_=;`BRd$zM`!?r&)xfR5O3nA^QytNPm}4tWPFOB5f{15 zVg}*3h=OgRJ9v682uq1j{!jK=2?;3Kv2~GIkV9nzG8^JUQthbw-p#< zFE}aLc?=rAC+LCB8=D5%4_f1vJwO9{E;$B5%hTF*(E!O^UXE<(1^WMP}_oDUBHA!{ffKE@lCG-@fp1)iIDomlB8#e zosN6*>TfcYwyXUnl=2pw7NlY!&py;paT#j_`Y3EH$u<}W=lL4dPyI;TdOnoGCFi)P z!tx`RcS5p*OrqE3Z^Gj$*n>IsQN81Levv6x=!AP}n!$+9=BwOn^(CXt2n@q{+=A;DWT&LXf z<1AN&i61U=%-ND?xVtp3Q#umA)J=cFK)bnRmYxNP=qX#AH0kN3!<%5xX<%O&y0J1y z@?k0=NucXWo@C?&GD=M&cxTdxPY0LCNmTeGAT8z1$|kGgyCzt_5@!QGp}-TEi*E04W;^q^e_v@ zYm|6zHu2m{N{XqSXf?jcY^D`{g6dk`aqs`I+sMx5p;_y-FYI^99+jV50WOjX@{c)$ znBD|QP)eNiP$gPLPel}VmajxuZj3OAr^Q`ZD+&Rnu$TrufRdr6;)tT&@U!0U;$0UR+dPv`H z!ELyXm|A{Ll9N2cxZt*`b9}u@ok0JM^kpVp3!CVsTM7F$c=s5&PI<3NYC+u?24L58 zj08YCLhetsg^{5aKGG$j9oNjE#=^Y`u#H1<-bhsQtrqjD*-wc5I2uuJZSh*yHaQ`Z zU8WK7tI9`!^ip<1g@VqW7lC44R0P8q z?`OBK?`9dB^HQA0iJa|ejS}azLRd-r=B9oeX=>8pZeT%as*e@rS4$4Tr#?dd+X zG2@QyH_GFX>Oq8gEBWqr;@q$17nSWzb5R7pYNfG)2P>$0Ey@+KL76VO+rKN|0{5q> zy1q(sNG3cK89JD5VbKjpD}9USpGSIkbL}&GX1$B9_aFD4yzOGAvxov|x{6&e<~ap{ zXCu3Wa#~A}L2|}T7=b1te&(9PQHj|I-~Y9Kca&URJZ)V(Eew6!Y(31dMOtmpuZ_uy zW4u$&FLY8ampKp_`>hMaYRQzw8(P+*qCPWYb0~EP=s8Eod-KMc?yC~()rGs+s7^v) zI$BVizdQHZi%{u6lcqCAq9bsNQmmf(4kzPcu1qU|Tmt0Pvi2bqoCLsLfm9_pY=uq<+>&}r?x>6X% zna*Sp7mpU_*U*1{hQ$v3e~rKU3qV)%uPEoon!loGV!juHa&DCQHU0jMa(*ztjzGU6 z5F;jkMfslt(eHrg4G?yo_!XfTDlmY*PZz%foHrO)pY$u%iOvB2%QgLuaK0sBjmWPU zApVK)r!Dz?>3Jo^_N-qqec?|!{?oyJUwmFvuwwfw?vkA?{u}B29p`+-VkPKTATirH lCrH09JfC!b88>uM4ZV$m;PZW$OU+&$a#zX14$tl|Iw literal 0 HcmV?d00001 From 9d90fb48f565ff5319bca0ff1acef2cbe95bf417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Tue, 17 Jun 2025 04:00:15 -0800 Subject: [PATCH 23/44] seed log --- Refhub/seed-log.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Refhub/seed-log.txt diff --git a/Refhub/seed-log.txt b/Refhub/seed-log.txt new file mode 100644 index 00000000..38699751 --- /dev/null +++ b/Refhub/seed-log.txt @@ -0,0 +1,5 @@ +[6/17/2025 2:52:18 AM] Starting seeding... +[6/17/2025 3:03:28 AM] Starting seeding... +[6/17/2025 3:03:28 AM] Author file exists: True +[6/17/2025 3:03:31 AM] Authors count: 5 +[6/17/2025 3:03:35 AM] SaveChanges Done. From 27793e20d4c5d94c0c775bf5271b4df7ce3a5184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:29:14 -0800 Subject: [PATCH 24/44] add Book Keyword wxcel file --- Refhub/SeedData/BookKeywordData.xlsx | Bin 0 -> 4766 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/BookKeywordData.xlsx diff --git a/Refhub/SeedData/BookKeywordData.xlsx b/Refhub/SeedData/BookKeywordData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..262d8d533cc8f0a4bf9c524303715a35041fd5fc GIT binary patch literal 4766 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 literal 0 HcmV?d00001 From 014e42eb0ffe43f8911e40e837ad2b070aec8e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:29:33 -0800 Subject: [PATCH 25/44] add book relation excel file --- Refhub/SeedData/BookRelationData.xlsx | Bin 0 -> 5448 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/BookRelationData.xlsx diff --git a/Refhub/SeedData/BookRelationData.xlsx b/Refhub/SeedData/BookRelationData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a9a1790b75e931fd5b1d0532a56de47d94758027 GIT binary patch literal 5448 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 Nzk%pHSCIYq^?#VJK~n$# literal 0 HcmV?d00001 From 60ce36bbb33f212b945c5316d4ab9e8ff13ae5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:29:45 -0800 Subject: [PATCH 26/44] add category excel file --- Refhub/SeedData/CategoryData.xlsx | Bin 0 -> 5773 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/CategoryData.xlsx diff --git a/Refhub/SeedData/CategoryData.xlsx b/Refhub/SeedData/CategoryData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f4804920cb519559e11d77c078e792f63355edbe GIT binary patch literal 5773 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 literal 0 HcmV?d00001 From 9e52a9f09e98a0ed28cfd580477f59bff8b0fef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:30:03 -0800 Subject: [PATCH 27/44] add keyword excel file --- Refhub/SeedData/KeywordData.xlsx | Bin 0 -> 5499 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Refhub/SeedData/KeywordData.xlsx diff --git a/Refhub/SeedData/KeywordData.xlsx b/Refhub/SeedData/KeywordData.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..c42e37b639be96ef2bb3da74b31f5cf7cccd4744 GIT binary patch literal 5499 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 z z9{X+42yqg11a1l42n@!)k7&@e2cOK zM`D-O-ahB~BBiW%Z+C`;L~g5jLfQJt&DUClwFm9HViY9&=VPF|aBs0R4U{{fMd%r` z_#C6O`XT<(=~?qx^GknRHkKP}PNtO~VrN4U7+=kb|@QxrXHS8p}#m6Fxb6Ox(Vw}r~d zS=V$2TQ%n85U)6XH{|k=kBw<-Xs0up(@E6_Oe8OR+rsA3MjZz-K*V@Z+-Jomf=Y^A zk5q#Ccd&y^j0L2XMA|X9t(RzsUFaMd%6|B~gN=&QIo*b5v8bB)-cY9vq@(8t111Vz_ zY(syC!}VJxtCmNz{iM{^0eSRg#mWWW&ZA8yixo9h*iofGsc6WPcwI{JaIkYsm?ImB z(CQY|6cB_z6m#mxnyc_dWbaLi<%700BQc1_qZcZ5o9g`hhuG3B*&7M(#C~i78(Q+X zV+qANeZ91MMX0;RRT7wAKO!Qdfk;l*)`7^w1(H?9b_i)0TupMRgDQIr6!?7SGuJfY zsGgQCfW_*C^l-(Lf)tAN6IpC5Q#_l)()1^C-ifL}a?(n9Kcl?V;_&Eg{+j9E`~VW$ z;4ETyon6bFdbLg$c5$`4^tC+IZ;*+UDrk1UpRIiSphmT=Yo^3`P!;~g(dCQT891YT z5es5DTvxI?W!22MixnZ0uA7WUv8Pwc*K)E<=8k}MLEc_Y3EPtgjYoM~F71{`HdeGx zL8E=$puRYkzR<>L3jwg1RL@drk!<$yu1wEdVDM-Nw@H(>4?uNbds7f=!CFx5!zIq2 zZNOePkuC?i4FI8=PjYk{VB=&Ba&>Zc6SQ`6h5T%SvXTaV8mbVqWhiLmN3z1mYq8+H zC4ma&ram`EImv7M6UOfOpYiCRZY}7?m!@5KdV=d`OT|yHSBge}Y$kCO!?SoLAAmki z57w|W{2rOUAGdoAB4y&=XiPHeiw!n{^3}1l-6k)*|E*S`k&Lf%a-WfFxoUM7JWEq- z98ol5g*=v+!4&xJ7YMw;Y5eFIptYr@bh~hYee|-<6Mz?&hmC#DTT3KJa1Nkz(i5W>Tbi4MO;_;MkPYr*xElxc0$mp<4ws}xW0>=2lw4?B*sGJ0(&0hq!S{{ z<9naz@lh4=r=MnEiPp>!w{UX1>!9DP4-aPFg3OmXr3a{C!cJ=Py)j8=?>c%iE(t+d zVdoj%I1Fy{{z0dte`;#cQ2f~ottlDWjgkGQrjMPSe@WV=v+;9yf;RE@J@i-)3?x-v z2N>@v6;T<}Lr0D8)_$YSfAOwc{jUT}-pU41H;<BNc$R^E^I7|3mSVz)ESH^Wwc<$tW zucb12{;4KOug-txm#^fc{wlUfhN>Jj$bh z&0r0u%OjrHC8sWb>jJ4#&u^eQG$jA*WGEb0Ao_$)ciwrWJA1*>$;2NMq=|t^iS@t7 zTnzv(=WiA#bm#XE%fH;{b?|i`^&7l|^WR<7b%yIkjc+NzuyF#Xea*v&cf^P>xKRsE{8r#{|*1A>_M8?Xh{G70`xZk L9p`TpKmYw7P55LC literal 0 HcmV?d00001 From 9ba5f287277edfb11eabc23489c0100c378fff30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:33:03 -0800 Subject: [PATCH 28/44] add ReadKeywordFromExcel method --- Refhub/Data/Seed/ExcelSeeder.cs | 72 ++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index babe87b5..87fe022e 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -7,15 +7,21 @@ namespace Refhub.Data.Seed { public static class ExcelSeeder { + public static void License() + { + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + } + + // Read Data from Author File public static List ReadAuthorsFromExcel(string filePath) { - ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + License(); var authors = new List(); using (var package = new ExcelPackage(new FileInfo(filePath))) { - var workSheet = package.Workbook.workSheets[0]; + var workSheet = package.Workbook.Worksheets[0]; int rowCount = workSheet.Dimension.Rows; for (int row = 2; row <= rowCount; row++) @@ -24,7 +30,7 @@ public static List ReadAuthorsFromExcel(string filePath) var slug = workSheet.Cells[row, 2].Text; if (!String.IsNullOrWhiteSpace(fullName) && !String.IsNullOrWhiteSpace(slug)) - { + { authors.Add(new Author { FullName = fullName, @@ -39,14 +45,14 @@ public static List ReadAuthorsFromExcel(string filePath) // Read Data from Book File public static List ReadBooksFromExcel(string filePath) { - ExcelPackage.LicenseContext= LicenseContext.NonCommercial; + License(); var books = new List(); using (var package = new ExcelPackage(new FileInfo(filePath))) { var workSheet = package.Workbook.Worksheets[0]; int rowCount = workSheet.Dimension.Rows; - for(int row = 2; row <= rowCount; row++) + for (int row = 2; row <= rowCount; row++) { var title = workSheet.Cells[row, 1].Text; var slug = workSheet.Cells[row, 2].Text; @@ -77,5 +83,59 @@ public static List ReadBooksFromExcel(string filePath) } return books; } + + // Read Data from BookAuthor Excel file + public static List ReadBookAuthorFromExcel(string filePath) + { + License(); + var bookAuthors = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + for (int row = 2; row < rowCount; row++) + { + var authorId = workSheet.Cells[row, 1].Text; + var bookId = workSheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(authorId) && !String.IsNullOrWhiteSpace(bookId)) + bookAuthors.Add(new BookAuthor + { + AuthorId = Convert.ToInt32(authorId), + BookId = Convert.ToInt32(bookId) + }); + } + } + return bookAuthors; + } + + // Read Data from KeyWord Excel file + public static List ReadKeywordFromExcel(string filePath) + { + License(); + var keywords = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + for (int row = 2; row < rowCount; row++) + { + var keyword = workSheet.Cells[row, 1].Text; + + if (!String.IsNullOrWhiteSpace(keyword)) + { + keywords.Add(new Keyword + { + Word = keyword, + }); + } + } + } + return keywords; + } + + } -} +} \ No newline at end of file From de9dc5cd3f35f436b2d585685f9995620960c8db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:33:50 -0800 Subject: [PATCH 29/44] add ReadCategoryFromExcel Method --- Refhub/Data/Seed/ExcelSeeder.cs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index 87fe022e..c191b093 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -136,6 +136,37 @@ public static List ReadKeywordFromExcel(string filePath) return keywords; } + // Read Data from Category Excel file + public static List ReadCategoryFromExcel(string filePath) + { + License(); + var categories = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + + for (int row = 2; row < rowCount; row++) + { + var name = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; + var description = workSheet.Cells[row, 3].Text; + + if (!String.IsNullOrWhiteSpace(name) && !String.IsNullOrWhiteSpace(slug) && !String.IsNullOrWhiteSpace(description)) + { + categories.Add(new Category + { + Name = name, + Description = description, + slug = slug + }); + } + } + } + return categories; + } + } } \ No newline at end of file From 2956c651d2e821e057273bc268867ec1bcb937fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:35:20 -0800 Subject: [PATCH 30/44] add ReadBookRelationFromExcel method --- Refhub/Data/Seed/ExcelSeeder.cs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index c191b093..ddc42a83 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -167,6 +167,37 @@ public static List ReadCategoryFromExcel(string filePath) return categories; } + // Read Data from BookRelation Excel file + public static List ReadBookRelationFromExcel(string filePath) + { + License(); + var bookRelations = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + var rowCount = workSheet.Dimension.Rows; + + for (int row = 2; row < rowCount; row++) + { + var bookId = workSheet.Cells[row, 1].Text; + var relationBookId = workSheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(relationBookId)) + { + bookRelations.Add(new BookRelation + { + BookId = Convert.ToInt32(bookId), + RelatedBookId = Convert.ToInt32(relationBookId) + }); + } + } + } + return bookRelations; + } + + + } } \ No newline at end of file From 01a2b46caa42818b26e0414de392b279ea32ddcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:36:15 -0800 Subject: [PATCH 31/44] add ReadBookKeywordFromExcel Method --- Refhub/Data/Seed/ExcelSeeder.cs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index ddc42a83..45bd7cca 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -196,8 +196,33 @@ public static List ReadBookRelationFromExcel(string filePath) return bookRelations; } + // Read Data from BookKeyword Excel file + public static List ReadBookKeywordFromExcel(string filePath) + { + License(); + var keywords = new List(); + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + var rowCount = workSheet.Dimension.Rows; + + for (int row = 2; row < keywords.Count; row++) + { + var bookId = workSheet.Cells[row, 1].Text; + var keywordId = workSheet.Cells[row, 2].Text; - + if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(keywordId)) + { + keywords.Add(new BookKeyword + { + BookId = Convert.ToInt32(bookId), + KeywordId = Convert.ToInt32(keywordId) + }); + } + } + return keywords; + } + } } } \ No newline at end of file From c704aae37ec8d795494bba18a1bd5eff19200210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:36:32 -0800 Subject: [PATCH 32/44] Apply changes --- Refhub/Data/Seed/DataSeeder.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 6f434780..33b2b518 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -13,22 +13,22 @@ public static void SeedInitialData(IServiceProvider serviceProvider) db.Database.Migrate(); // Authors - if (!db.Authors.Any()) - { + //if (!db.Authors.Any()) + //{ var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); - var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); - db.Authors.AddRange(authors); - } - // Books - if (!db.Books.Any()) - { - var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); - var books = ExcelSeeder.ReadBooksFromExcel(bookPath); - db.Books.AddRange(books); - } + var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); + db.Authors.AddRange(authors); + //} - db.SaveChanges(); + // Books + //if (!db.Books.Any()) + //{ + // var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); + // var books = ExcelSeeder.ReadBooksFromExcel(bookPath); + // db.Books.AddRange(books); + //} + db.SaveChanges(); } } } From 05e7bfff6b1252e45e92036c9fd29309cbd661bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:36:43 -0800 Subject: [PATCH 33/44] Updata solution --- Refhub/Refhub.csproj | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Refhub/Refhub.csproj b/Refhub/Refhub.csproj index 09831fcc..a974ebd2 100644 --- a/Refhub/Refhub.csproj +++ b/Refhub/Refhub.csproj @@ -24,4 +24,13 @@ + + + PreserveNewest + + + PreserveNewest + + + From ff087d84d015160b3f15dd28beb3847d11a82729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:38:56 -0800 Subject: [PATCH 34/44] update class --- Refhub/Data/Seed/DataSeeder.cs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 33b2b518..61d3555e 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -12,23 +12,19 @@ public static void SeedInitialData(IServiceProvider serviceProvider) db.Database.Migrate(); - // Authors - //if (!db.Authors.Any()) - //{ - var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); + var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); db.Authors.AddRange(authors); - //} - - // Books - //if (!db.Books.Any()) - //{ - // var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); - // var books = ExcelSeeder.ReadBooksFromExcel(bookPath); - // db.Books.AddRange(books); - //} - db.SaveChanges(); + + + var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); + var books = ExcelSeeder.ReadBooksFromExcel(bookPath); + db.Books.AddRange(books); + + + + db.SaveChanges(); } } } From 5aa664c18c8bc688d5df279338349778f3e4ec1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:39:28 -0800 Subject: [PATCH 35/44] add comment for authors --- Refhub/Data/Seed/DataSeeder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 61d3555e..7e7b67c1 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -12,12 +12,12 @@ public static void SeedInitialData(IServiceProvider serviceProvider) db.Database.Migrate(); - + // Author var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); db.Authors.AddRange(authors); - + var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); var books = ExcelSeeder.ReadBooksFromExcel(bookPath); db.Books.AddRange(books); From 4e0da024e1463419e47aeee8d289be69220bf157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:39:49 -0800 Subject: [PATCH 36/44] add comment for Book --- Refhub/Data/Seed/DataSeeder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 7e7b67c1..c446face 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -17,7 +17,7 @@ public static void SeedInitialData(IServiceProvider serviceProvider) var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); db.Authors.AddRange(authors); - + // Book var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); var books = ExcelSeeder.ReadBooksFromExcel(bookPath); db.Books.AddRange(books); From 748344fa91bb9cbb6154cb3982222da14e3056c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:42:48 -0800 Subject: [PATCH 37/44] add AuthorBook Initial --- Refhub/Data/Seed/DataSeeder.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index c446face..01db9a59 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -23,6 +23,12 @@ public static void SeedInitialData(IServiceProvider serviceProvider) db.Books.AddRange(books); + // AuthorBook + var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData"); + var authorBook = ExcelSeeder.ReadBooksFromExcel(authorBookPath); + db.Books.AddRange(authorBook); + + db.SaveChanges(); } From ac2c70408829f2cfd5f425f8181b6ccdbd505f0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:50:50 -0800 Subject: [PATCH 38/44] add BookKeyword initial --- Refhub/Data/Seed/DataSeeder.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 01db9a59..5c5158e5 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -26,7 +26,13 @@ public static void SeedInitialData(IServiceProvider serviceProvider) // AuthorBook var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData"); var authorBook = ExcelSeeder.ReadBooksFromExcel(authorBookPath); - db.Books.AddRange(authorBook); + db.BookAuthors.AddRange(authorBook); + + + // BookKeyword + var bookKeywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookKeywordData"); + var bookKetword = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); + db.BookKeywords.AddRange(bookKetword); From 2b7826bdde20111647b09f141be381319ff6f370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:52:37 -0800 Subject: [PATCH 39/44] book relational initial --- Refhub/Data/Seed/DataSeeder.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 5c5158e5..5a8f78b3 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -34,7 +34,12 @@ public static void SeedInitialData(IServiceProvider serviceProvider) var bookKetword = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); db.BookKeywords.AddRange(bookKetword); - + // BookRelation + var bookRelationPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookRelationData"); + var bookRelation = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); + db.BookKeywords.AddRange(bookRelation); + + // db.SaveChanges(); } From 06d35a4931355922af481d20aab464a0e29ea008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D8=B3=D9=87=DB=8C=D9=84=20=D8=A7=DB=8C=D9=85=D8=A7=D9=86?= =?UTF-8?q?=DB=8C=20=D8=A7=D8=AE=D8=AA=DB=8C=D8=A7=D8=B1?= Date: Wed, 25 Jun 2025 04:55:17 -0800 Subject: [PATCH 40/44] add All Initialize --- Refhub/Data/Seed/DataSeeder.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 5a8f78b3..303613ec 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -39,7 +39,15 @@ public static void SeedInitialData(IServiceProvider serviceProvider) var bookRelation = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); db.BookKeywords.AddRange(bookRelation); - // + // Category + var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "CategorynData"); + var Category = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); + db.BookKeywords.AddRange(Category); + + // Keyword + var keywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "KeywordData"); + var Keyword = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); + db.BookKeywords.AddRange(Keyword); db.SaveChanges(); } From 6e73a4a749005ded96541e6065bb0adc7ada7653 Mon Sep 17 00:00:00 2001 From: Hootan Hemmati Date: Tue, 1 Jul 2025 22:00:34 +0330 Subject: [PATCH 41/44] Update ci.yml (#100) (#104) --- .github/workflows/ci.yml | 63 +--------------------------------------- 1 file changed, 1 insertion(+), 62 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 296b2e79..e7b7643c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -225,68 +225,7 @@ jobs: # ===================================== path: ./publish retention-days: 7 compression-level: 6 - # ===================================== - # 📊 FINAL STATUS REPORT - # ===================================== - status-report: - name: 📊 Build Status Report - runs-on: ubuntu-latest - needs: [build, docker, package] - if: always() - timeout-minutes: 5 - - steps: - - name: 💬 PR Comment (On Failure) - if: failure() && github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `## ❌ Build Pipeline Failed - - **Build Status**: Failed ❌ - **Run ID**: ${{ github.run_id }} - **Commit**: ${{ github.sha }} - - Please check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details. - - ### 🔧 Next Steps: - - Review the failed job logs - - Fix any compilation errors - - Ensure dependencies are properly restored - - --- - *This comment was automatically generated by the build pipeline* 🤖` - }) - - - name: 💬 PR Comment (On Success) - if: success() && github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: `## ✅ Build Pipeline Successful - - **Build Status**: Passed ✅ - **Run ID**: ${{ github.run_id }} - **Commit**: ${{ github.sha }} - ### 🎉 Build Completed: - - ✅ Build successful (Debug & Release) - - ✅ Docker image built and tested - - ✅ Artifacts created - - **Ready for review and merge!** 🚀 - - --- - *This comment was automatically generated by the build pipeline* 🤖` - }) - + # ===================================== # 🔧 WORKFLOW CONFIGURATION NOTES # ===================================== From 985e416a9c772034740dfa4eca720237c2c7eb3f Mon Sep 17 00:00:00 2001 From: Mohammad Faraji Date: Fri, 4 Jul 2025 22:27:09 +0330 Subject: [PATCH 42/44] Fix Bug File DataSeeder And ExcelSeeder --- Refhub/Data/Seed/DataSeeder.cs | 30 ++++++++++--------- Refhub/Data/Seed/ExcelSeeder.cs | 51 +++++++++++++++++++++------------ 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 303613ec..8f0c5d7f 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -1,5 +1,7 @@ using Microsoft.EntityFrameworkCore; using Refhub.Data.Context; +using Refhub.Data.Models; +using Refhub.Models.DTO; namespace Refhub.Data.Seed { @@ -24,30 +26,30 @@ public static void SeedInitialData(IServiceProvider serviceProvider) // AuthorBook - var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData"); - var authorBook = ExcelSeeder.ReadBooksFromExcel(authorBookPath); + var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData.xlsx"); + var authorBook = ExcelSeeder.ReadBookAuthorFromExcel(authorBookPath); db.BookAuthors.AddRange(authorBook); // BookKeyword - var bookKeywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookKeywordData"); - var bookKetword = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); - db.BookKeywords.AddRange(bookKetword); + var bookKeywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookKeywordData.xlsx"); + var bookKeyword = ExcelSeeder.ReadBookKeywordFromExcel(bookKeywordPath); + db.BookKeywords.AddRange(bookKeyword); // BookRelation - var bookRelationPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookRelationData"); - var bookRelation = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); - db.BookKeywords.AddRange(bookRelation); + var bookRelationPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookRelationData.xlsx"); + var bookRelation = ExcelSeeder.ReadBookRelationFromExcel(bookRelationPath); + db.BookRelations.AddRange(bookRelation); // Category - var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "CategorynData"); - var Category = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); - db.BookKeywords.AddRange(Category); + var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "CategoryData.xlsx"); + var category = ExcelSeeder.ReadCategoryFromExcel(categoryPath); + db.Categories.AddRange(category); // Keyword - var keywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "KeywordData"); - var Keyword = ExcelSeeder.ReadBooksFromExcel(bookKeywordPath); - db.BookKeywords.AddRange(Keyword); + var keywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "KeywordData.xlsx"); + var keyword = ExcelSeeder.ReadKeywordFromExcel(keywordPath); + db.Keywords.AddRange(keyword); db.SaveChanges(); } diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index 45bd7cca..bcfd387e 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -16,30 +16,45 @@ public static void License() // Read Data from Author File public static List ReadAuthorsFromExcel(string filePath) { - License(); - var authors = new List(); - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - int rowCount = workSheet.Dimension.Rows; + License(); + var authors = new List(); - for (int row = 2; row <= rowCount; row++) + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var fullName = workSheet.Cells[row, 1].Text; - var slug = workSheet.Cells[row, 2].Text; + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; - if (!String.IsNullOrWhiteSpace(fullName) && !String.IsNullOrWhiteSpace(slug)) + for (int row = 2; row <= rowCount; row++) { - authors.Add(new Author + var fullName = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(fullName) && !String.IsNullOrWhiteSpace(slug)) { - FullName = fullName, - Slug = slug - }); + authors.Add(new Author + { + FullName = fullName, + Slug = slug + }); + } } + return authors; } - return authors; + // ... existing code ... + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading authors from Excel: {ex.Message}", ex); + } + + } // Read Data from Book File @@ -94,7 +109,7 @@ public static List ReadBookAuthorFromExcel(string filePath) { var workSheet = package.Workbook.Worksheets[0]; int rowCount = workSheet.Dimension.Rows; - for (int row = 2; row < rowCount; row++) + for (int row = 2; row <= rowCount; row++) { var authorId = workSheet.Cells[row, 1].Text; var bookId = workSheet.Cells[row, 2].Text; @@ -120,7 +135,7 @@ public static List ReadKeywordFromExcel(string filePath) { var workSheet = package.Workbook.Worksheets[0]; int rowCount = workSheet.Dimension.Rows; - for (int row = 2; row < rowCount; row++) + for (int row = 2; row <= rowCount; row++) { var keyword = workSheet.Cells[row, 1].Text; @@ -178,7 +193,7 @@ public static List ReadBookRelationFromExcel(string filePath) var workSheet = package.Workbook.Worksheets[0]; var rowCount = workSheet.Dimension.Rows; - for (int row = 2; row < rowCount; row++) + for (int row = 2; row <= rowCount; row++) { var bookId = workSheet.Cells[row, 1].Text; var relationBookId = workSheet.Cells[row, 2].Text; @@ -206,7 +221,7 @@ public static List ReadBookKeywordFromExcel(string filePath) var workSheet = package.Workbook.Worksheets[0]; var rowCount = workSheet.Dimension.Rows; - for (int row = 2; row < keywords.Count; row++) + for (int row = 2; row <= rowCount; row++) { var bookId = workSheet.Cells[row, 1].Text; var keywordId = workSheet.Cells[row, 2].Text; From 7b715be88f6ff760c63184489aadf75786bd6246 Mon Sep 17 00:00:00 2001 From: Mohammad Faraji Date: Mon, 7 Jul 2025 22:37:32 +0330 Subject: [PATCH 43/44] Update Namespace --- Refhub/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Refhub/Program.cs b/Refhub/Program.cs index 677d535c..40ab9a85 100644 --- a/Refhub/Program.cs +++ b/Refhub/Program.cs @@ -2,7 +2,7 @@ using Refhub.Data.Context; using Refhub.Data.Models; using Refhub.Data.Seed; -using Refhub.Tools.ExtentionMethod; +using Refhub.Tools.ExtensionMethod; namespace Refhub; From a4e87dec3b112bc26a0a297fbca3693951ce9dc8 Mon Sep 17 00:00:00 2001 From: Hootan Hemmati Date: Sat, 26 Jul 2025 11:10:50 +0330 Subject: [PATCH 44/44] Enhance data seeding with error handling and logging - Added error handling in `DataSeeder.cs` to log exceptions and prevent duplicate entries during seeding. - Improved data reading methods in `ExcelSeeder.cs` with file existence checks and better error handling. - Created new `Authors` and `BookAuthors` tables in the migration file `20250616145440_AddAuthorTable.cs`. - Updated `Program.cs` to include error handling for initial data seeding. - Added `EPPlus` package reference in `Refhub.csproj` for Excel file operations. - Revised `seed-log.txt` to improve logging format and detail. --- Refhub/Data/Seed/DataSeeder.cs | 126 ++++++-- Refhub/Data/Seed/ExcelSeeder.cs | 290 +++++++++++------- .../20250616145440_AddAuthorTable.cs | 31 ++ Refhub/Program.cs | 11 +- Refhub/Refhub.csproj | 1 + Refhub/seed-log.txt | 5 - 6 files changed, 315 insertions(+), 149 deletions(-) delete mode 100644 Refhub/seed-log.txt diff --git a/Refhub/Data/Seed/DataSeeder.cs b/Refhub/Data/Seed/DataSeeder.cs index 8f0c5d7f..8468f3bc 100644 --- a/Refhub/Data/Seed/DataSeeder.cs +++ b/Refhub/Data/Seed/DataSeeder.cs @@ -9,49 +9,111 @@ public static class DataSeeder { public static void SeedInitialData(IServiceProvider serviceProvider) { - using var scope = serviceProvider.CreateScope(); - var db = scope.ServiceProvider.GetRequiredService(); + try + { + using var scope = serviceProvider.CreateScope(); + var db = scope.ServiceProvider.GetRequiredService(); - db.Database.Migrate(); + db.Database.Migrate(); - // Author - var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); - var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); - db.Authors.AddRange(authors); + // Check if data already exists to avoid duplicates + if (db.Authors.Any()) + { + Console.WriteLine("Database already seeded. Skipping..."); + return; + } - // Book - var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); - var books = ExcelSeeder.ReadBooksFromExcel(bookPath); - db.Books.AddRange(books); + // Author + var authorPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorData.xlsx"); + if (File.Exists(authorPath)) + { + var authors = ExcelSeeder.ReadAuthorsFromExcel(authorPath); + if (authors.Any()) + { + db.Authors.AddRange(authors); + } + } + // Category (seed before books since books reference categories) + var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "CategoryData.xlsx"); + if (File.Exists(categoryPath)) + { + var categories = ExcelSeeder.ReadCategoryFromExcel(categoryPath); + if (categories.Any()) + { + db.Categories.AddRange(categories); + } + } - // AuthorBook - var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData.xlsx"); - var authorBook = ExcelSeeder.ReadBookAuthorFromExcel(authorBookPath); - db.BookAuthors.AddRange(authorBook); + // Keyword (seed before BookKeyword) + var keywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "KeywordData.xlsx"); + if (File.Exists(keywordPath)) + { + var keywords = ExcelSeeder.ReadKeywordFromExcel(keywordPath); + if (keywords.Any()) + { + db.Keywords.AddRange(keywords); + } + } + // Save basic entities first + db.SaveChanges(); - // BookKeyword - var bookKeywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookKeywordData.xlsx"); - var bookKeyword = ExcelSeeder.ReadBookKeywordFromExcel(bookKeywordPath); - db.BookKeywords.AddRange(bookKeyword); + // Book + var bookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookData.xlsx"); + if (File.Exists(bookPath)) + { + var books = ExcelSeeder.ReadBooksFromExcel(bookPath); + if (books.Any()) + { + db.Books.AddRange(books); + } + } - // BookRelation - var bookRelationPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookRelationData.xlsx"); - var bookRelation = ExcelSeeder.ReadBookRelationFromExcel(bookRelationPath); - db.BookRelations.AddRange(bookRelation); + // Save books before relationships + db.SaveChanges(); - // Category - var categoryPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "CategoryData.xlsx"); - var category = ExcelSeeder.ReadCategoryFromExcel(categoryPath); - db.Categories.AddRange(category); + // AuthorBook + var authorBookPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "AuthorBookData.xlsx"); + if (File.Exists(authorBookPath)) + { + var authorBooks = ExcelSeeder.ReadBookAuthorFromExcel(authorBookPath); + if (authorBooks.Any()) + { + db.BookAuthors.AddRange(authorBooks); + } + } - // Keyword - var keywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "KeywordData.xlsx"); - var keyword = ExcelSeeder.ReadKeywordFromExcel(keywordPath); - db.Keywords.AddRange(keyword); + // BookKeyword + var bookKeywordPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookKeywordData.xlsx"); + if (File.Exists(bookKeywordPath)) + { + var bookKeywords = ExcelSeeder.ReadBookKeywordFromExcel(bookKeywordPath); + if (bookKeywords.Any()) + { + db.BookKeywords.AddRange(bookKeywords); + } + } - db.SaveChanges(); + // BookRelation + var bookRelationPath = Path.Combine(Directory.GetCurrentDirectory(), "SeedData", "BookRelationData.xlsx"); + if (File.Exists(bookRelationPath)) + { + var bookRelations = ExcelSeeder.ReadBookRelationFromExcel(bookRelationPath); + if (bookRelations.Any()) + { + db.BookRelations.AddRange(bookRelations); + } + } + + db.SaveChanges(); + Console.WriteLine("Database seeding completed successfully."); + } + catch (Exception ex) + { + Console.WriteLine($"Error during database seeding: {ex.Message}"); + throw; + } } } } diff --git a/Refhub/Data/Seed/ExcelSeeder.cs b/Refhub/Data/Seed/ExcelSeeder.cs index bcfd387e..3229479f 100644 --- a/Refhub/Data/Seed/ExcelSeeder.cs +++ b/Refhub/Data/Seed/ExcelSeeder.cs @@ -7,6 +7,11 @@ namespace Refhub.Data.Seed { public static class ExcelSeeder { + static ExcelSeeder() + { + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + } + public static void License() { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; @@ -16,7 +21,6 @@ public static void License() // Read Data from Author File public static List ReadAuthorsFromExcel(string filePath) { - try { License(); @@ -41,9 +45,8 @@ public static List ReadAuthorsFromExcel(string filePath) }); } } - return authors; } - // ... existing code ... + return authors; } catch (FileNotFoundException) { @@ -53,191 +56,258 @@ public static List ReadAuthorsFromExcel(string filePath) { throw new InvalidOperationException($"Error reading authors from Excel: {ex.Message}", ex); } - - } // Read Data from Book File public static List ReadBooksFromExcel(string filePath) { - License(); - var books = new List(); - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - int rowCount = workSheet.Dimension.Rows; - - for (int row = 2; row <= rowCount; row++) + License(); + var books = new List(); + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var title = workSheet.Cells[row, 1].Text; - var slug = workSheet.Cells[row, 2].Text; - var pageCountText = workSheet.Cells[row, 3].Text; - var filePathCell = workSheet.Cells[row, 4].Text; - var imagePath = workSheet.Cells[row, 5].Text; - var categoryIdText = workSheet.Cells[row, 6].Text; - var userId = workSheet.Cells[row, 7].Text; + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + for (int row = 2; row <= rowCount; row++) + { + var title = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; + var pageCountText = workSheet.Cells[row, 3].Text; + var filePathCell = workSheet.Cells[row, 4].Text; + var imagePath = workSheet.Cells[row, 5].Text; + var categoryIdText = workSheet.Cells[row, 6].Text; + var userId = workSheet.Cells[row, 7].Text; - if (string.IsNullOrWhiteSpace(title) || string.IsNullOrWhiteSpace(slug)) - continue; + if (string.IsNullOrWhiteSpace(title) || string.IsNullOrWhiteSpace(slug)) + continue; - int.TryParse(pageCountText, out int pageCount); - int.TryParse(categoryIdText, out int categoryId); + int.TryParse(pageCountText, out int pageCount); + int.TryParse(categoryIdText, out int categoryId); - books.Add(new Book - { - Title = title, - Slug = slug, - PageCount = pageCount, - FilePath = filePathCell, - ImagePath = imagePath, - CategoryId = categoryId, - UserId = string.IsNullOrWhiteSpace(userId) ? null : userId - }); + books.Add(new Book + { + Title = title, + Slug = slug, + PageCount = pageCount, + FilePath = filePathCell, + ImagePath = imagePath, + CategoryId = categoryId, + UserId = string.IsNullOrWhiteSpace(userId) ? null : userId + }); + } } + return books; + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading books from Excel: {ex.Message}", ex); } - return books; } // Read Data from BookAuthor Excel file public static List ReadBookAuthorFromExcel(string filePath) { - License(); - var bookAuthors = new List(); - - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - int rowCount = workSheet.Dimension.Rows; - for (int row = 2; row <= rowCount; row++) + License(); + var bookAuthors = new List(); + + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var authorId = workSheet.Cells[row, 1].Text; - var bookId = workSheet.Cells[row, 2].Text; + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + for (int row = 2; row <= rowCount; row++) + { + var authorId = workSheet.Cells[row, 1].Text; + var bookId = workSheet.Cells[row, 2].Text; - if (!String.IsNullOrWhiteSpace(authorId) && !String.IsNullOrWhiteSpace(bookId)) - bookAuthors.Add(new BookAuthor + if (!String.IsNullOrWhiteSpace(authorId) && !String.IsNullOrWhiteSpace(bookId) + && int.TryParse(authorId, out int authorIdValue) && int.TryParse(bookId, out int bookIdValue)) { - AuthorId = Convert.ToInt32(authorId), - BookId = Convert.ToInt32(bookId) - }); + bookAuthors.Add(new BookAuthor + { + AuthorId = authorIdValue, + BookId = bookIdValue + }); + } + } } + return bookAuthors; + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading book authors from Excel: {ex.Message}", ex); } - return bookAuthors; } // Read Data from KeyWord Excel file public static List ReadKeywordFromExcel(string filePath) { - License(); - var keywords = new List(); - - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - int rowCount = workSheet.Dimension.Rows; - for (int row = 2; row <= rowCount; row++) - { - var keyword = workSheet.Cells[row, 1].Text; + License(); + var keywords = new List(); - if (!String.IsNullOrWhiteSpace(keyword)) + using (var package = new ExcelPackage(new FileInfo(filePath))) + { + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; + for (int row = 2; row <= rowCount; row++) { - keywords.Add(new Keyword + var keyword = workSheet.Cells[row, 1].Text; + + if (!String.IsNullOrWhiteSpace(keyword)) { - Word = keyword, - }); + keywords.Add(new Keyword + { + Word = keyword, + }); + } } } + return keywords; + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading keywords from Excel: {ex.Message}", ex); } - return keywords; } // Read Data from Category Excel file public static List ReadCategoryFromExcel(string filePath) { - License(); - var categories = new List(); - - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - int rowCount = workSheet.Dimension.Rows; + License(); + var categories = new List(); - for (int row = 2; row < rowCount; row++) + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var name = workSheet.Cells[row, 1].Text; - var slug = workSheet.Cells[row, 2].Text; - var description = workSheet.Cells[row, 3].Text; + var workSheet = package.Workbook.Worksheets[0]; + int rowCount = workSheet.Dimension.Rows; - if (!String.IsNullOrWhiteSpace(name) && !String.IsNullOrWhiteSpace(slug) && !String.IsNullOrWhiteSpace(description)) + for (int row = 2; row <= rowCount; row++) { - categories.Add(new Category + var name = workSheet.Cells[row, 1].Text; + var slug = workSheet.Cells[row, 2].Text; + var description = workSheet.Cells[row, 3].Text; + + if (!String.IsNullOrWhiteSpace(name) && !String.IsNullOrWhiteSpace(slug) && !String.IsNullOrWhiteSpace(description)) { - Name = name, - Description = description, - slug = slug - }); + categories.Add(new Category + { + Name = name, + Description = description, + slug = slug + }); + } } } + return categories; + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading categories from Excel: {ex.Message}", ex); } - return categories; } // Read Data from BookRelation Excel file public static List ReadBookRelationFromExcel(string filePath) { - License(); - var bookRelations = new List(); - - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - var rowCount = workSheet.Dimension.Rows; + License(); + var bookRelations = new List(); - for (int row = 2; row <= rowCount; row++) + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var bookId = workSheet.Cells[row, 1].Text; - var relationBookId = workSheet.Cells[row, 2].Text; + var workSheet = package.Workbook.Worksheets[0]; + var rowCount = workSheet.Dimension.Rows; - if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(relationBookId)) + for (int row = 2; row <= rowCount; row++) { - bookRelations.Add(new BookRelation + var bookId = workSheet.Cells[row, 1].Text; + var relationBookId = workSheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(relationBookId) + && int.TryParse(bookId, out int bookIdValue) && int.TryParse(relationBookId, out int relationBookIdValue)) { - BookId = Convert.ToInt32(bookId), - RelatedBookId = Convert.ToInt32(relationBookId) - }); + bookRelations.Add(new BookRelation + { + BookId = bookIdValue, + RelatedBookId = relationBookIdValue + }); + } } } + return bookRelations; + } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading book relations from Excel: {ex.Message}", ex); } - return bookRelations; } // Read Data from BookKeyword Excel file public static List ReadBookKeywordFromExcel(string filePath) { - License(); - var keywords = new List(); - using (var package = new ExcelPackage(new FileInfo(filePath))) + try { - var workSheet = package.Workbook.Worksheets[0]; - var rowCount = workSheet.Dimension.Rows; - - for (int row = 2; row <= rowCount; row++) + License(); + var keywords = new List(); + using (var package = new ExcelPackage(new FileInfo(filePath))) { - var bookId = workSheet.Cells[row, 1].Text; - var keywordId = workSheet.Cells[row, 2].Text; + var workSheet = package.Workbook.Worksheets[0]; + var rowCount = workSheet.Dimension.Rows; - if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(keywordId)) + for (int row = 2; row <= rowCount; row++) { - keywords.Add(new BookKeyword + var bookId = workSheet.Cells[row, 1].Text; + var keywordId = workSheet.Cells[row, 2].Text; + + if (!String.IsNullOrWhiteSpace(bookId) && !String.IsNullOrWhiteSpace(keywordId) + && int.TryParse(bookId, out int bookIdValue) && int.TryParse(keywordId, out int keywordIdValue)) { - BookId = Convert.ToInt32(bookId), - KeywordId = Convert.ToInt32(keywordId) - }); + keywords.Add(new BookKeyword + { + BookId = bookIdValue, + KeywordId = keywordIdValue + }); + } } } return keywords; } + catch (FileNotFoundException) + { + throw new InvalidOperationException($"Excel file not found: {filePath}"); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Error reading book keywords from Excel: {ex.Message}", ex); + } } - } } \ No newline at end of file diff --git a/Refhub/Migrations/20250616145440_AddAuthorTable.cs b/Refhub/Migrations/20250616145440_AddAuthorTable.cs index d4e157b5..e11685f1 100644 --- a/Refhub/Migrations/20250616145440_AddAuthorTable.cs +++ b/Refhub/Migrations/20250616145440_AddAuthorTable.cs @@ -23,11 +23,42 @@ protected override void Up(MigrationBuilder migrationBuilder) table: "Books", column: "Slug", unique: true); + + migrationBuilder.CreateTable( + name: "Authors", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + FullName = table.Column(maxLength: 256, nullable: false), + Slug = table.Column(nullable: false) + }, + constraints: table => table.PrimaryKey("PK_Authors", x => x.Id)); + + migrationBuilder.CreateTable( + name: "BookAuthors", + columns: table => new + { + BookId = table.Column(nullable: false), + AuthorId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BookAuthors", x => new { x.BookId, x.AuthorId }); + table.ForeignKey("FK_BookAuthors_Books_BookId", x => x.BookId, "Books", "Id", onDelete: ReferentialAction.Cascade); + table.ForeignKey("FK_BookAuthors_Authors_AuthorId", x => x.AuthorId, "Authors", "Id", onDelete: ReferentialAction.Cascade); + }); } /// protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropTable( + name: "BookAuthors"); + + migrationBuilder.DropTable( + name: "Authors"); + migrationBuilder.DropIndex( name: "IX_Books_Slug", table: "Books"); diff --git a/Refhub/Program.cs b/Refhub/Program.cs index f40ead2e..5182f610 100644 --- a/Refhub/Program.cs +++ b/Refhub/Program.cs @@ -77,9 +77,16 @@ public static void Main(string[] args) // Configure browser launching based on environment variables app.UseBrowserLaunchMode(); - // Seed initial data from Excel files - DataSeeder.SeedInitialData(app.Services); + try + { + DataSeeder.SeedInitialData(app.Services); + } + catch (Exception ex) + { + Console.WriteLine($"Failed to seed data: {ex.Message}"); + // Continue startup even if seeding fails in development + } app.Run(); } diff --git a/Refhub/Refhub.csproj b/Refhub/Refhub.csproj index 57b5f9f2..0d00478d 100644 --- a/Refhub/Refhub.csproj +++ b/Refhub/Refhub.csproj @@ -14,6 +14,7 @@ + diff --git a/Refhub/seed-log.txt b/Refhub/seed-log.txt deleted file mode 100644 index 38699751..00000000 --- a/Refhub/seed-log.txt +++ /dev/null @@ -1,5 +0,0 @@ -[6/17/2025 2:52:18 AM] Starting seeding... -[6/17/2025 3:03:28 AM] Starting seeding... -[6/17/2025 3:03:28 AM] Author file exists: True -[6/17/2025 3:03:31 AM] Authors count: 5 -[6/17/2025 3:03:35 AM] SaveChanges Done.