diff --git a/docs/研发/架构基础.xmind b/docs/研发/架构基础.xmind
new file mode 100644
index 00000000..7e8dc68d
Binary files /dev/null and b/docs/研发/架构基础.xmind differ
diff --git a/labs/EFCoreTest/.gitignore b/labs/EFCoreTest/.gitignore
index cd5894bd..11ee0d93 100644
--- a/labs/EFCoreTest/.gitignore
+++ b/labs/EFCoreTest/.gitignore
@@ -15,4 +15,5 @@ release
Release
Logs
logs
-node_modules
\ No newline at end of file
+node_modules
+cockroach-data
\ No newline at end of file
diff --git a/labs/EFCoreTest/EFCoreTest.csproj b/labs/EFCoreTest/EFCoreTest.csproj
index be8ce481..20a7edf4 100644
--- a/labs/EFCoreTest/EFCoreTest.csproj
+++ b/labs/EFCoreTest/EFCoreTest.csproj
@@ -8,6 +8,7 @@
+
diff --git a/labs/EFCoreTest/Entities.cs b/labs/EFCoreTest/Entities.cs
new file mode 100644
index 00000000..5bd069a4
--- /dev/null
+++ b/labs/EFCoreTest/Entities.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+
+namespace EFCoreTest
+{
+ public class Entity
+ {
+ public Guid Id { get; set; }
+ public DateTime Created { get; set; }
+ public DateTime LastChanged { get; set; }
+ public string RowVersion { get; set; }
+ public Entity()
+ {
+ this.Id = Guid.NewGuid();
+ }
+
+ public override string ToString()
+ {
+ return this.Id.ToString();
+ }
+ }
+
+ 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; }
+ }
+}
\ No newline at end of file
diff --git a/labs/EFCoreTest/MyDbContext.cs b/labs/EFCoreTest/MyDbContext.cs
new file mode 100644
index 00000000..23d81ae0
--- /dev/null
+++ b/labs/EFCoreTest/MyDbContext.cs
@@ -0,0 +1,73 @@
+using Microsoft.EntityFrameworkCore;
+using System;
+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;");
+ ///https://www.cockroachlabs.com/docs/stable/build-a-csharp-app-with-cockroachdb.html
+ /// cockroach sql --insecure
+ /// CREATE DATABASE test;
+ /// DROP DATABASE test CASCADE;
+ /// \q
+ optionsBuilder.UseNpgsql("User ID=root;Host=localhost;Port=26257;Database=test;");
+ }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ foreach (var entity in modelBuilder.Model.GetEntityTypes())
+ {
+ if (entity.GetProperties().Any(o => o.Name == "Id"))
+ {
+ modelBuilder.Entity(entity.Name).HasKey("Id");
+ modelBuilder.Entity(entity.Name).Property("Id").ValueGeneratedNever();
+ }
+ if (entity.GetProperties().Any(o => o.Name == "RowVersion"))
+ {
+ modelBuilder.Entity(entity.Name).Property("RowVersion")?.IsConcurrencyToken().ValueGeneratedNever();
+ }
+ }
+ modelBuilder.Entity().Property(o => o.UserName).IsRequired().HasMaxLength(64);
+ modelBuilder.Entity().Property(o => o.Name).IsRequired().HasMaxLength(64); ;
+ 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 override int SaveChanges()
+ {
+ var entries = this.ChangeTracker.Entries().ToList();
+ foreach (var entry in entries)
+ {
+ if (entry.State == EntityState.Added || entry.State == EntityState.Modified)
+ {
+ if(entry.State == EntityState.Added)
+ {
+ var created = entry.Property("Created");
+ if (created != null)
+ {
+ created.CurrentValue = DateTime.UtcNow;
+ }
+ }
+ var rowVersionProperty = entry.Property("RowVersion");
+ if (rowVersionProperty != null)
+ {
+ rowVersionProperty.CurrentValue = Guid.NewGuid().ToString();
+ }
+ var lastModified = entry.Property("LastModified");
+ if (rowVersionProperty != lastModified)
+ {
+ lastModified.CurrentValue = DateTime.UtcNow;
+ }
+ }
+ Console.WriteLine($"id:{entry.Entity.ToString()},state:{entry.State}");
+ }
+ return base.SaveChanges();
+ }
+ }
+}
\ No newline at end of file
diff --git a/labs/EFCoreTest/Program.cs b/labs/EFCoreTest/Program.cs
index bc8edb74..184dc1b3 100644
--- a/labs/EFCoreTest/Program.cs
+++ b/labs/EFCoreTest/Program.cs
@@ -1,71 +1,42 @@
using Microsoft.EntityFrameworkCore;
-using System;
using System.Collections.Generic;
using System.Linq;
namespace EFCoreTest
{
- public class MyDbContext : DbContext
+ internal class Program
{
- 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)
+ private static void Main(string[] args)
{
using (var db = new MyDbContext())
{
+ var set = db.Set();
if (db.Database.EnsureCreated())
{
- db.Set().Add(new User { UserName = "test" });
+ set.Add(new User
+ {
+ UserName = "test",
+ UserRoles = new List
+ {
+ new UserRole
+ {
+ Role=new Role{
+ Name="admin"
+ }
+ }
+ }
+ });
db.SaveChanges();
}
- Console.WriteLine(db.Set().FirstOrDefault()?.UserName);
+ //foreach (var item in set.ToList())
+ //{
+ // set.Remove(item);
+ // db.SaveChanges();
+ //}
+ var user = set.Include(o => o.UserRoles).ThenInclude(o => o.Role).FirstOrDefault();
+ user.UserRoles.FirstOrDefault().Role.Name = "test";
+ db.SaveChanges();
}
}
}
-}
+}
\ No newline at end of file
diff --git a/labs/EFCoreTest/cockroach-v2.0.5.windows-6.2-amd64/cockroach.exe b/labs/EFCoreTest/cockroach-v2.0.5.windows-6.2-amd64/cockroach.exe
new file mode 100644
index 00000000..5873190a
Binary files /dev/null and b/labs/EFCoreTest/cockroach-v2.0.5.windows-6.2-amd64/cockroach.exe differ
diff --git a/tools/dbeaver-ce-6.3.5-win32.win32.x86_64.zip b/tools/dbeaver-ce-6.3.5-win32.win32.x86_64.zip
new file mode 100644
index 00000000..5b04cbca
Binary files /dev/null and b/tools/dbeaver-ce-6.3.5-win32.win32.x86_64.zip differ