diff --git a/docs/研发/产品.xmind b/docs/研发/产品.xmind
new file mode 100644
index 00000000..016c9946
Binary files /dev/null and b/docs/研发/产品.xmind differ
diff --git a/labs/EFCoreTest/.gitignore b/labs/EFCoreTest/.gitignore
new file mode 100644
index 00000000..cd5894bd
--- /dev/null
+++ b/labs/EFCoreTest/.gitignore
@@ -0,0 +1,18 @@
+*.bak
+*.suo
+*.db
+*.db-shm
+*.db-wal
+*.user
+.vs
+obj
+Obj
+bin
+Bin
+debug
+Debug
+release
+Release
+Logs
+logs
+node_modules
\ No newline at end of file
diff --git a/labs/EFCoreTest/EFCoreTest.csproj b/labs/EFCoreTest/EFCoreTest.csproj
new file mode 100644
index 00000000..be8ce481
--- /dev/null
+++ b/labs/EFCoreTest/EFCoreTest.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
diff --git a/labs/EFCoreTest/EFCoreTest.sln b/labs/EFCoreTest/EFCoreTest.sln
new file mode 100644
index 00000000..e05c74d6
--- /dev/null
+++ b/labs/EFCoreTest/EFCoreTest.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29814.53
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EFCoreTest", "EFCoreTest.csproj", "{4BB784D0-B6BB-4450-9E34-F64EA74B5555}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4BB784D0-B6BB-4450-9E34-F64EA74B5555}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4BB784D0-B6BB-4450-9E34-F64EA74B5555}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4BB784D0-B6BB-4450-9E34-F64EA74B5555}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4BB784D0-B6BB-4450-9E34-F64EA74B5555}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C2F655E3-914B-48C5-A6C5-7674A05F5CFD}
+ EndGlobalSection
+EndGlobal
diff --git a/labs/EFCoreTest/Program.cs b/labs/EFCoreTest/Program.cs
new file mode 100644
index 00000000..bc8edb74
--- /dev/null
+++ b/labs/EFCoreTest/Program.cs
@@ -0,0 +1,71 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace EFCoreTest
+{
+ public class MyDbContext : DbContext
+ {
+ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+ {
+ optionsBuilder.UseSqlite("Data Source=data.db;");
+ //optionsBuilder.UseMySql("Server=139.180.143.95;Port=3306;Database=test;Uid=admin;Pwd=admin;");
+ }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity();
+ modelBuilder.Entity();
+ modelBuilder.Entity().HasOne(o => o.User).WithMany(o => o.UserRoles).HasForeignKey(o => o.UserId);
+ modelBuilder.Entity().HasOne(o => o.Role).WithMany(o => o.UserRoles).HasForeignKey(o => o.RoleId);
+ modelBuilder.Entity().HasIndex(o => new { o.UserId, o.RoleId }).IsUnique();
+ }
+ }
+
+ public class Entity
+ {
+ public Guid Id { get; set; }
+
+ public Entity()
+ {
+ this.Id = Guid.NewGuid();
+ }
+ }
+
+ public class User : Entity
+ {
+ public string UserName { get; set; }
+ public List UserRoles { get; set; } = new List();
+ }
+
+ public class Role : Entity
+ {
+ public string Name { get; set; }
+ public List UserRoles { get; set; } = new List();
+ }
+
+ public class UserRole : Entity
+ {
+ public Guid UserId { get; set; }
+ public Guid RoleId { get; set; }
+ public User User { get; set; }
+ public Role Role { get; set; }
+ }
+
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ using (var db = new MyDbContext())
+ {
+ if (db.Database.EnsureCreated())
+ {
+ db.Set().Add(new User { UserName = "test" });
+ db.SaveChanges();
+ }
+ Console.WriteLine(db.Set().FirstOrDefault()?.UserName);
+ }
+ }
+ }
+}