diff --git a/NetCoreBBS.sln b/NetCoreBBS.sln
index 9e158e9..5b0d262 100644
--- a/NetCoreBBS.sln
+++ b/NetCoreBBS.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26228.4
+VisualStudioVersion = 15.0.26403.7
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{94F5C8A4-D158-4A10-AD26-C635A376CC92}"
EndProject
@@ -12,6 +12,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCoreBBS", "src\NetCoreBBS\NetCoreBBS.csproj", "{7FEB182D-CFA4-4DA2-A9FF-0ABF794F8A4D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Infrastructure", "src\Infrastructure\Infrastructure.csproj", "{1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApplicationCore", "src\ApplicationCore\ApplicationCore.csproj", "{65AC78E9-500F-42B5-954D-93F841F5D0F1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{D25B2B42-A638-4F40-B51C-DCF41A3C8F4C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "tests\UnitTests\UnitTests.csproj", "{152AAF50-21A3-477D-BB56-A25E56D4B611}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -22,11 +30,26 @@ Global
{7FEB182D-CFA4-4DA2-A9FF-0ABF794F8A4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7FEB182D-CFA4-4DA2-A9FF-0ABF794F8A4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7FEB182D-CFA4-4DA2-A9FF-0ABF794F8A4D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {65AC78E9-500F-42B5-954D-93F841F5D0F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65AC78E9-500F-42B5-954D-93F841F5D0F1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65AC78E9-500F-42B5-954D-93F841F5D0F1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65AC78E9-500F-42B5-954D-93F841F5D0F1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {152AAF50-21A3-477D-BB56-A25E56D4B611}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {152AAF50-21A3-477D-BB56-A25E56D4B611}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {152AAF50-21A3-477D-BB56-A25E56D4B611}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {152AAF50-21A3-477D-BB56-A25E56D4B611}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7FEB182D-CFA4-4DA2-A9FF-0ABF794F8A4D} = {94F5C8A4-D158-4A10-AD26-C635A376CC92}
+ {1AA24171-F5E6-4E7A-B227-A6ECD34DA2E7} = {94F5C8A4-D158-4A10-AD26-C635A376CC92}
+ {65AC78E9-500F-42B5-954D-93F841F5D0F1} = {94F5C8A4-D158-4A10-AD26-C635A376CC92}
+ {152AAF50-21A3-477D-BB56-A25E56D4B611} = {D25B2B42-A638-4F40-B51C-DCF41A3C8F4C}
EndGlobalSection
EndGlobal
diff --git a/README.md b/README.md
index fcd60b9..93d3c6d 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,23 @@
# NETCoreBBS
ASP.NET Core Light forum NETCoreBBS
-ASP.NET Core 1.0 + EF Core 1.0 Sqlite + Bootstrap
+ASP.NET Core + EF Core Sqlite + Bootstrap
.NET Core 跨平台轻论坛
-[live demo](http://104.251.232.80/)
+[使用技术点介绍](http://www.cnblogs.com/linezero/p/NETCoreBBS.html)
+## 开发
+
+1. `git clone https://github.com/linezero/NETCoreBBS.git`
+2. 使用 Visual Studio 2017 打开 `NetCoreBBS.sln`
+3. 点击 `调试->开始调试` 即可运行起来,或者直接点击工具栏上的`NetCoreBBS`即可。
+
+注意:默认为80端口,可能会和本地端口冲突,可以到Program.cs 中更改 `.UseUrls("http://*:80")`,然后更改启动URL既可。
+
+
+## 功能
-## 已开发
1. 节点功能
1. 主题发布
2. 主题回复
@@ -16,6 +25,7 @@ ASP.NET Core 1.0 + EF Core 1.0 Sqlite + Bootstrap
3. 用户登录注册
4. 主题置顶
5. 后台管理
+6. 个人中心
## License
NETCoreBBS is licensed under [MIT](LICENSE).
diff --git a/src/ApplicationCore/ApplicationCore.csproj b/src/ApplicationCore/ApplicationCore.csproj
new file mode 100644
index 0000000..cdfd19f
--- /dev/null
+++ b/src/ApplicationCore/ApplicationCore.csproj
@@ -0,0 +1,12 @@
+
+
+
+ netstandard1.4
+ NetCoreBBS
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ApplicationCore/Entities/BaseEntity.cs b/src/ApplicationCore/Entities/BaseEntity.cs
new file mode 100644
index 0000000..0ecea62
--- /dev/null
+++ b/src/ApplicationCore/Entities/BaseEntity.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NetCoreBBS.Entities
+{
+ public class BaseEntity
+ {
+ public int Id { get; set; }
+ }
+}
diff --git a/src/NetCoreBBS/Models/Topic.cs b/src/ApplicationCore/Entities/Topic.cs
similarity index 50%
rename from src/NetCoreBBS/Models/Topic.cs
rename to src/ApplicationCore/Entities/Topic.cs
index 1755cf0..2050191 100644
--- a/src/NetCoreBBS/Models/Topic.cs
+++ b/src/ApplicationCore/Entities/Topic.cs
@@ -1,34 +1,36 @@
using System;
using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Linq;
-using System.Threading.Tasks;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Entities
{
- public class Topic
+ public class Topic:BaseEntity
{
- public int Id { get; set; }
public int NodeId { get; set; }
- public Guid UserId { get; set; }
- [Required]
+ public TopicNode Node { get; set; }
+ public string UserId { get; set; }
+ public User User { get; set; }
public string Email { get; set; }
- [Required]
public string Title { get; set; }
- [Required]
public string Content { get; set; }
///
/// 置顶权重
///
public int Top { get; set; }
- ///
- /// 精华
- ///
- public bool Good { get; set; }
+ public TopicType Type { get; set; }
public int ViewCount { get; set; }
public int ReplyCount { get; set; }
- public Guid LastReplyUserId { get; set; }
+ public string LastReplyUserId { get; set; }
+ public User LastReplyUser { get; set; }
public DateTime LastReplyTime { get; set; }
public DateTime CreateOn { get; set; }
+ public virtual List Replys { get; set; }
+ }
+ public enum TopicType
+ {
+ Delete=0,
+ Normal = 1,
+ Top=2,
+ Good=3,
+ Hot=4
}
}
diff --git a/src/NetCoreBBS/Models/TopicNode.cs b/src/ApplicationCore/Entities/TopicNode.cs
similarity index 80%
rename from src/NetCoreBBS/Models/TopicNode.cs
rename to src/ApplicationCore/Entities/TopicNode.cs
index 8af6865..b14fd0d 100644
--- a/src/NetCoreBBS/Models/TopicNode.cs
+++ b/src/ApplicationCore/Entities/TopicNode.cs
@@ -3,11 +3,10 @@
using System.Linq;
using System.Threading.Tasks;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Entities
{
- public class TopicNode
+ public class TopicNode:BaseEntity
{
- public int Id { get; set; }
public int ParentId { get; set; }
public string NodeName { get; set; }
public string Name { get; set; }
diff --git a/src/NetCoreBBS/Models/TopicReply.cs b/src/ApplicationCore/Entities/TopicReply.cs
similarity index 66%
rename from src/NetCoreBBS/Models/TopicReply.cs
rename to src/ApplicationCore/Entities/TopicReply.cs
index 64a3d5a..fc6497c 100644
--- a/src/NetCoreBBS/Models/TopicReply.cs
+++ b/src/ApplicationCore/Entities/TopicReply.cs
@@ -4,16 +4,14 @@
using System.Linq;
using System.Threading.Tasks;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Entities
{
- public class TopicReply
+ public class TopicReply:BaseEntity
{
- public int Id { get; set; }
public int TopicId { get; set; }
- public Guid UserId { get; set; }
- [Required]
+ public string ReplyUserId { get; set; }
+ public User ReplyUser { get; set; }
public string ReplyEmail { get; set; }
- [Required]
public string ReplyContent { get; set; }
public DateTime CreateOn { get; set; }
}
diff --git a/src/NetCoreBBS/Models/User.cs b/src/ApplicationCore/Entities/User.cs
similarity index 95%
rename from src/NetCoreBBS/Models/User.cs
rename to src/ApplicationCore/Entities/User.cs
index c63e6ba..ab4d060 100644
--- a/src/NetCoreBBS/Models/User.cs
+++ b/src/ApplicationCore/Entities/User.cs
@@ -4,7 +4,7 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Entities
{
public class User: IdentityUser
{
diff --git a/src/NetCoreBBS/Models/UserTopic.cs b/src/ApplicationCore/Entities/UserCollection.cs
similarity index 51%
rename from src/NetCoreBBS/Models/UserTopic.cs
rename to src/ApplicationCore/Entities/UserCollection.cs
index ec2f42e..a66ffbf 100644
--- a/src/NetCoreBBS/Models/UserTopic.cs
+++ b/src/ApplicationCore/Entities/UserCollection.cs
@@ -3,13 +3,14 @@
using System.Linq;
using System.Threading.Tasks;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Entities
{
- public class UserTopic
+ public class UserCollection:BaseEntity
{
- public int Id { get; set; }
- public Guid UserId { get; set; }
+ public string UserId { get; set; }
public int TopicId { get; set; }
+ public Topic Topic { get; set; }
+ public int State { get; set; }
public DateTime CreateOn { get; set; }
}
}
diff --git a/src/ApplicationCore/Entities/UserMessage.cs b/src/ApplicationCore/Entities/UserMessage.cs
new file mode 100644
index 0000000..db87b48
--- /dev/null
+++ b/src/ApplicationCore/Entities/UserMessage.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace NetCoreBBS.Entities
+{
+ public class UserMessage:BaseEntity
+ {
+ public string SendUserId { get; set; }
+ public User SendUser { get; set; }
+ public string ReceiveUserId { get; set; }
+ public User ReceiveUser { get; set; }
+ public string Type { get; set; }
+ public string Content { get; set; }
+ public int State { get; set; }
+ public DateTime CreateOn { get; set; }
+ }
+}
diff --git a/src/ApplicationCore/Interfaces/IRepository.cs b/src/ApplicationCore/Interfaces/IRepository.cs
new file mode 100644
index 0000000..618d8b0
--- /dev/null
+++ b/src/ApplicationCore/Interfaces/IRepository.cs
@@ -0,0 +1,18 @@
+using NetCoreBBS.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Text;
+
+namespace NetCoreBBS.Interfaces
+{
+ public interface IRepository where T: BaseEntity
+ {
+ T GetById(int id);
+ IEnumerable List();
+ IEnumerable List(Expression> predicate);
+ void Add(T entity);
+ void Delete(T entity);
+ void Edit(T entity);
+ }
+}
diff --git a/src/ApplicationCore/Interfaces/ITopicReplyRepository.cs b/src/ApplicationCore/Interfaces/ITopicReplyRepository.cs
new file mode 100644
index 0000000..b81defa
--- /dev/null
+++ b/src/ApplicationCore/Interfaces/ITopicReplyRepository.cs
@@ -0,0 +1,8 @@
+using NetCoreBBS.Entities;
+
+namespace NetCoreBBS.Interfaces
+{
+ public interface ITopicReplyRepository:IRepository
+ {
+ }
+}
diff --git a/src/ApplicationCore/Interfaces/ITopicRepository.cs b/src/ApplicationCore/Interfaces/ITopicRepository.cs
new file mode 100644
index 0000000..e4916d6
--- /dev/null
+++ b/src/ApplicationCore/Interfaces/ITopicRepository.cs
@@ -0,0 +1,14 @@
+using NetCoreBBS.Entities;
+using System;
+using System.Collections.Generic;
+using System.Linq.Expressions;
+using System.Text;
+
+namespace NetCoreBBS.Interfaces
+{
+ public interface ITopicRepository:IRepository
+ {
+ Page PageList(int pagesize,int pageindex);
+ Page PageList(Expression> predicate, int pagesize, int pageindex);
+ }
+}
diff --git a/src/ApplicationCore/Page.cs b/src/ApplicationCore/Page.cs
new file mode 100644
index 0000000..740a2e6
--- /dev/null
+++ b/src/ApplicationCore/Page.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace NetCoreBBS.Entities
+{
+ public class Page
+ where T : class
+ {
+ public int Total { get; private set; }
+ public int PageSize { get; private set; }
+ public List List { get; private set; }
+ public Page(List list, int pageSize, int total)
+ {
+ this.List = list;
+ this.PageSize = pageSize;
+ this.Total = total;
+ }
+
+ public int GetPageCount()
+ {
+ return (Total + PageSize - 1) / PageSize;
+ }
+ }
+}
diff --git a/src/NetCoreBBS/Models/DataContext.cs b/src/Infrastructure/DataContext.cs
similarity index 84%
rename from src/NetCoreBBS/Models/DataContext.cs
rename to src/Infrastructure/DataContext.cs
index a9a6e6c..aa3d2d3 100644
--- a/src/NetCoreBBS/Models/DataContext.cs
+++ b/src/Infrastructure/DataContext.cs
@@ -4,8 +4,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
+using NetCoreBBS.Entities;
-namespace NetCoreBBS.Models
+namespace NetCoreBBS.Infrastructure
{
public class DataContext : IdentityDbContext
{
@@ -17,7 +18,7 @@ public DataContext(DbContextOptions options)
public DbSet TopicReplys { get; set; }
public DbSet TopicNodes { get; set; }
public DbSet UserMessages { get; set; }
- public DbSet UserTopics { get; set; }
+ public DbSet UserTopics { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -27,7 +28,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity().ToTable("TopicNode");
modelBuilder.Entity().ToTable("User");
modelBuilder.Entity().ToTable("UserMessage");
- modelBuilder.Entity().ToTable("UserTopic");
+ modelBuilder.Entity().ToTable("UserCollection");
}
}
}
diff --git a/src/Infrastructure/Infrastructure.csproj b/src/Infrastructure/Infrastructure.csproj
new file mode 100644
index 0000000..66cdb87
--- /dev/null
+++ b/src/Infrastructure/Infrastructure.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netstandard1.4
+ NetCoreBBS.Infrastructure
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Infrastructure/Migrations/20170606024516_InitMigration.Designer.cs b/src/Infrastructure/Migrations/20170606024516_InitMigration.Designer.cs
new file mode 100644
index 0000000..2af5659
--- /dev/null
+++ b/src/Infrastructure/Migrations/20170606024516_InitMigration.Designer.cs
@@ -0,0 +1,412 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using NetCoreBBS.Infrastructure;
+using NetCoreBBS.Entities;
+
+namespace NetCoreBBS.Infrastructure.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ [Migration("20170606024516_InitMigration")]
+ partial class InitMigration
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.1.2");
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider");
+
+ b.Property("Name");
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.Topic", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content");
+
+ b.Property("CreateOn");
+
+ b.Property("Email");
+
+ b.Property("LastReplyTime");
+
+ b.Property("LastReplyUserId");
+
+ b.Property("NodeId");
+
+ b.Property("ReplyCount");
+
+ b.Property("Title");
+
+ b.Property("Top");
+
+ b.Property("Type");
+
+ b.Property("UserId");
+
+ b.Property("ViewCount");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LastReplyUserId");
+
+ b.HasIndex("NodeId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Topic");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.TopicNode", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateOn");
+
+ b.Property("Description");
+
+ b.Property("Name");
+
+ b.Property("NodeName");
+
+ b.Property("Order");
+
+ b.Property("ParentId");
+
+ b.HasKey("Id");
+
+ b.ToTable("TopicNode");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.TopicReply", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateOn");
+
+ b.Property("ReplyContent");
+
+ b.Property("ReplyEmail");
+
+ b.Property("ReplyUserId");
+
+ b.Property("TopicId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ReplyUserId");
+
+ b.HasIndex("TopicId");
+
+ b.ToTable("TopicReply");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccessFailedCount");
+
+ b.Property("Avatar");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("CreateOn");
+
+ b.Property("Email")
+ .HasMaxLength(256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("GitHub");
+
+ b.Property("LastTime");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("Profile");
+
+ b.Property("Score");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TopicCount");
+
+ b.Property("TopicReplyCount");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("Url");
+
+ b.Property("UserName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex");
+
+ b.ToTable("User");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.UserCollection", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateOn");
+
+ b.Property("State");
+
+ b.Property("TopicId");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TopicId");
+
+ b.ToTable("UserCollection");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.UserMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content");
+
+ b.Property("CreateOn");
+
+ b.Property("ReceiveUserId");
+
+ b.Property("SendUserId");
+
+ b.Property("State");
+
+ b.Property("Type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ReceiveUserId");
+
+ b.HasIndex("SendUserId");
+
+ b.ToTable("UserMessage");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+ .WithMany("Claims")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.User")
+ .WithMany("Claims")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.User")
+ .WithMany("Logins")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole")
+ .WithMany("Users")
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("NetCoreBBS.Entities.User")
+ .WithMany("Roles")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.Topic", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.User", "LastReplyUser")
+ .WithMany()
+ .HasForeignKey("LastReplyUserId");
+
+ b.HasOne("NetCoreBBS.Entities.TopicNode", "Node")
+ .WithMany()
+ .HasForeignKey("NodeId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("NetCoreBBS.Entities.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.TopicReply", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.User", "ReplyUser")
+ .WithMany()
+ .HasForeignKey("ReplyUserId");
+
+ b.HasOne("NetCoreBBS.Entities.Topic")
+ .WithMany("Replys")
+ .HasForeignKey("TopicId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.UserCollection", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.Topic", "Topic")
+ .WithMany()
+ .HasForeignKey("TopicId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.UserMessage", b =>
+ {
+ b.HasOne("NetCoreBBS.Entities.User", "ReceiveUser")
+ .WithMany()
+ .HasForeignKey("ReceiveUserId");
+
+ b.HasOne("NetCoreBBS.Entities.User", "SendUser")
+ .WithMany()
+ .HasForeignKey("SendUserId");
+ });
+ }
+ }
+}
diff --git a/src/Infrastructure/Migrations/20170606024516_InitMigration.cs b/src/Infrastructure/Migrations/20170606024516_InitMigration.cs
new file mode 100644
index 0000000..88a9f0c
--- /dev/null
+++ b/src/Infrastructure/Migrations/20170606024516_InitMigration.cs
@@ -0,0 +1,417 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace NetCoreBBS.Infrastructure.Migrations
+{
+ public partial class InitMigration : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "AspNetRoles",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ ConcurrencyStamp = table.Column(nullable: true),
+ Name = table.Column(maxLength: 256, nullable: true),
+ NormalizedName = table.Column(maxLength: 256, nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserTokens",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ LoginProvider = table.Column(nullable: false),
+ Name = table.Column(nullable: false),
+ Value = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
+ });
+
+ migrationBuilder.CreateTable(
+ name: "TopicNode",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ CreateOn = table.Column(nullable: false),
+ Description = table.Column(nullable: true),
+ Name = table.Column(nullable: true),
+ NodeName = table.Column(nullable: true),
+ Order = table.Column(nullable: false),
+ ParentId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TopicNode", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "User",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ AccessFailedCount = table.Column(nullable: false),
+ Avatar = table.Column(nullable: true),
+ ConcurrencyStamp = table.Column(nullable: true),
+ CreateOn = table.Column(nullable: false),
+ Email = table.Column(maxLength: 256, nullable: true),
+ EmailConfirmed = table.Column(nullable: false),
+ GitHub = table.Column(nullable: true),
+ LastTime = table.Column(nullable: false),
+ LockoutEnabled = table.Column(nullable: false),
+ LockoutEnd = table.Column(nullable: true),
+ NormalizedEmail = table.Column(maxLength: 256, nullable: true),
+ NormalizedUserName = table.Column(maxLength: 256, nullable: true),
+ PasswordHash = table.Column(nullable: true),
+ PhoneNumber = table.Column(nullable: true),
+ PhoneNumberConfirmed = table.Column(nullable: false),
+ Profile = table.Column(nullable: true),
+ Score = table.Column(nullable: false),
+ SecurityStamp = table.Column(nullable: true),
+ TopicCount = table.Column(nullable: false),
+ TopicReplyCount = table.Column(nullable: false),
+ TwoFactorEnabled = table.Column(nullable: false),
+ Url = table.Column(nullable: true),
+ UserName = table.Column(maxLength: 256, nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_User", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetRoleClaims",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(nullable: true),
+ RoleId = table.Column(nullable: false)
+ },
+ 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: "AspNetUserClaims",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(nullable: true),
+ UserId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AspNetUserClaims_User_UserId",
+ column: x => x.UserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserLogins",
+ columns: table => new
+ {
+ LoginProvider = table.Column(nullable: false),
+ ProviderKey = table.Column(nullable: false),
+ ProviderDisplayName = table.Column(nullable: true),
+ UserId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
+ table.ForeignKey(
+ name: "FK_AspNetUserLogins_User_UserId",
+ column: x => x.UserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "AspNetUserRoles",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ RoleId = table.Column(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_User_UserId",
+ column: x => x.UserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Topic",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Content = table.Column(nullable: true),
+ CreateOn = table.Column(nullable: false),
+ Email = table.Column(nullable: true),
+ LastReplyTime = table.Column(nullable: false),
+ LastReplyUserId = table.Column(nullable: true),
+ NodeId = table.Column(nullable: false),
+ ReplyCount = table.Column(nullable: false),
+ Title = table.Column(nullable: true),
+ Top = table.Column(nullable: false),
+ Type = table.Column(nullable: false),
+ UserId = table.Column(nullable: true),
+ ViewCount = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Topic", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Topic_User_LastReplyUserId",
+ column: x => x.LastReplyUserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_Topic_TopicNode_NodeId",
+ column: x => x.NodeId,
+ principalTable: "TopicNode",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Topic_User_UserId",
+ column: x => x.UserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserMessage",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ Content = table.Column(nullable: true),
+ CreateOn = table.Column(nullable: false),
+ ReceiveUserId = table.Column(nullable: true),
+ SendUserId = table.Column(nullable: true),
+ State = table.Column(nullable: false),
+ Type = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserMessage", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserMessage_User_ReceiveUserId",
+ column: x => x.ReceiveUserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_UserMessage_User_SendUserId",
+ column: x => x.SendUserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "TopicReply",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ CreateOn = table.Column(nullable: false),
+ ReplyContent = table.Column(nullable: true),
+ ReplyEmail = table.Column(nullable: true),
+ ReplyUserId = table.Column(nullable: true),
+ TopicId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_TopicReply", x => x.Id);
+ table.ForeignKey(
+ name: "FK_TopicReply_User_ReplyUserId",
+ column: x => x.ReplyUserId,
+ principalTable: "User",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Restrict);
+ table.ForeignKey(
+ name: "FK_TopicReply_Topic_TopicId",
+ column: x => x.TopicId,
+ principalTable: "Topic",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserCollection",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ CreateOn = table.Column(nullable: false),
+ State = table.Column(nullable: false),
+ TopicId = table.Column(nullable: false),
+ UserId = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserCollection", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserCollection_Topic_TopicId",
+ column: x => x.TopicId,
+ principalTable: "Topic",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "RoleNameIndex",
+ table: "AspNetRoles",
+ column: "NormalizedName",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AspNetRoleClaims_RoleId",
+ table: "AspNetRoleClaims",
+ column: "RoleId");
+
+ 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.CreateIndex(
+ name: "IX_Topic_LastReplyUserId",
+ table: "Topic",
+ column: "LastReplyUserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Topic_NodeId",
+ table: "Topic",
+ column: "NodeId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Topic_UserId",
+ table: "Topic",
+ column: "UserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_TopicReply_ReplyUserId",
+ table: "TopicReply",
+ column: "ReplyUserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_TopicReply_TopicId",
+ table: "TopicReply",
+ column: "TopicId");
+
+ migrationBuilder.CreateIndex(
+ name: "EmailIndex",
+ table: "User",
+ column: "NormalizedEmail");
+
+ migrationBuilder.CreateIndex(
+ name: "UserNameIndex",
+ table: "User",
+ column: "NormalizedUserName",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserCollection_TopicId",
+ table: "UserCollection",
+ column: "TopicId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserMessage_ReceiveUserId",
+ table: "UserMessage",
+ column: "ReceiveUserId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_UserMessage_SendUserId",
+ table: "UserMessage",
+ column: "SendUserId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "AspNetRoleClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserClaims");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserLogins");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserRoles");
+
+ migrationBuilder.DropTable(
+ name: "AspNetUserTokens");
+
+ migrationBuilder.DropTable(
+ name: "TopicReply");
+
+ migrationBuilder.DropTable(
+ name: "UserCollection");
+
+ migrationBuilder.DropTable(
+ name: "UserMessage");
+
+ migrationBuilder.DropTable(
+ name: "AspNetRoles");
+
+ migrationBuilder.DropTable(
+ name: "Topic");
+
+ migrationBuilder.DropTable(
+ name: "User");
+
+ migrationBuilder.DropTable(
+ name: "TopicNode");
+ }
+ }
+}
diff --git a/src/Infrastructure/Migrations/DataContextModelSnapshot.cs b/src/Infrastructure/Migrations/DataContextModelSnapshot.cs
new file mode 100644
index 0000000..6708b8b
--- /dev/null
+++ b/src/Infrastructure/Migrations/DataContextModelSnapshot.cs
@@ -0,0 +1,411 @@
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using NetCoreBBS.Infrastructure;
+using NetCoreBBS.Entities;
+
+namespace NetCoreBBS.Infrastructure.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ partial class DataContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+ modelBuilder
+ .HasAnnotation("ProductVersion", "1.1.2");
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider");
+
+ b.Property("Name");
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.Topic", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content");
+
+ b.Property("CreateOn");
+
+ b.Property("Email");
+
+ b.Property("LastReplyTime");
+
+ b.Property("LastReplyUserId");
+
+ b.Property("NodeId");
+
+ b.Property("ReplyCount");
+
+ b.Property("Title");
+
+ b.Property("Top");
+
+ b.Property("Type");
+
+ b.Property("UserId");
+
+ b.Property("ViewCount");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LastReplyUserId");
+
+ b.HasIndex("NodeId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Topic");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.TopicNode", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateOn");
+
+ b.Property("Description");
+
+ b.Property("Name");
+
+ b.Property("NodeName");
+
+ b.Property("Order");
+
+ b.Property("ParentId");
+
+ b.HasKey("Id");
+
+ b.ToTable("TopicNode");
+ });
+
+ modelBuilder.Entity("NetCoreBBS.Entities.TopicReply", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("CreateOn");
+
+ b.Property("ReplyContent");
+
+ b.Property("ReplyEmail");
+
+ b.Property("ReplyUserId");
+
+ b.Property