1. 程式人生 > 其它 >資料上下文dbcontext新增資料與Database資料庫的分庫分表,表對映,切換表,使用到了IModelCacheKeyFactory程式碼如下:

資料上下文dbcontext新增資料與Database資料庫的分庫分表,表對映,切換表,使用到了IModelCacheKeyFactory程式碼如下:

資料上下文dbcontext新增資料與Database資料庫的分庫分表,表對映,切換表,使用到了IModelCacheKeyFactory

程式碼如下:

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace EFCOREDB { class Program { static void Main(string[] args) { Console.WriteLine("Hello World!"); #region 測試 TestDBContext(); #endregion Console.Read(); } #region Database資料庫操作 ///
<summary> /// 測試資料庫的分庫分表,表對映,切換表 /// </summary> static void TestDBContext() { #region DBContext //DateTime datetime1 = DateTime.Now; //using (var context = new DynamicContext { CreateDateTime = datetime1 }) //{
// Console.WriteLine("開始刪除資料庫"); // context.Database.EnsureDeleted(); // Console.WriteLine("刪除成功"); // Console.WriteLine("開始建立資料庫"); // context.Database.EnsureCreated(); // Console.WriteLine("建立成功"); // var tablename = context.Model.FindEntityType(typeof(Test)).GetTableName(); // #region MyRegion // //context.Tests.Add(new Test { Title = "Great News One", Content = $"Hello World! I am the news of {datetime1}", CreateDateTime = datetime1 }); // //更新實體的方式 // //0、查詢實體,修改實體欄位,context.SaveChanges(); // //1、建立實體,context.Entry(建立的實體).State=EntityState.Modified; context.SaveChanges(); // //2、建立實體,context.Update(建立的實體); context.SaveChanges(); // //3、建立實體,context.DbSet<Test>.Attach(建立的實體); context.Entry(建立的實體).State=EntityState.Modified; context.SaveChanges(); // //3、建立實體,context.DbSet<Test>.Attach(建立的實體); context.ChangeTracker.DetectChanges(); context.SaveChanges(); // //3、建立實體,context.Attach(建立的實體); context.Entry(建立的實體).State=EntityState.Modified; context.SaveChanges(); // //4、context.ChangeTracker.TrackGraph(ss, e => { // // if ((e.Entry.Entity as Test) != null) // // { // // e.Entry.State = EntityState.Unchanged; // // } // // else // // { // // e.Entry.State = EntityState.Modified; // // } // //}); // //context.SaveChanges(); // #endregion // var ss = new Test { Title = "11", Content = $"111 {datetime1}", CreateDateTime = datetime1 }; // Console.WriteLine($"context.Entry(ss).State:{context.Entry(ss).State}"); // //context.Attach(ss);//告訴EF Core開始跟蹤person實體的更改,因為呼叫DbContext.Attach方法後,EF Core會將person實體的State值(可以通過testDBContext.Entry(ss).State檢視到)更改回EntityState.Unchanged,所以這裡testDBContext.Attach(ss)一定要放在下面一行testDBContext.Entry(ss).Property(p => p.Content).IsModified = true的前面,否者後面的testDBContext.SaveChanges方法呼叫後,資料庫不會被更新 // //context.Entry(ss).Property(p => p.Content).IsModified = true;//告訴EF Core實體ss的Content屬性已經更改。將testDBContext.Entry(person).Property(p => p.Name).IsModified設定為true後,也會將ss實體的State值(可以通過testDBContext.Entry(ss).State檢視到)更改為EntityState.Modified,這樣就保證了下面SaveChanges的時候會將ss實體的Content屬性值Update到資料庫中。 // //context.Entry(ss).Property(p => p.Content).IsModified = true; // //context.Tests.Attach(ss); // context.Attach(ss); // Console.WriteLine($"context.Entry(ss).State:{context.Entry(ss).State}"); // //context.ChangeTracker.DetectChanges(); // context.SaveChanges(); //} ////切換表 //DateTime datetime2 = DateTime.Now.AddDays(-1); //using (var context = new DynamicContext { CreateDateTime = datetime2 }) //{ // var tablename = context.Model.FindEntityType(typeof(Test)).GetTableName();//查詢實體對映到資料庫中對應的表名稱 // if (!tablename.Equals("20201118")) // { // //var str = GetMySQLSqls(datetime2); // var str = GetSqlServerSqls(datetime2); // //判斷是否存在表,不存在則建立 // using var cmd = context.Database.GetDbConnection().CreateCommand(); // cmd.CommandText = str[0]; // if (cmd.Connection.State != System.Data.ConnectionState.Open) // { // cmd.Connection.Open(); // } // var result = cmd.ExecuteScalar(); // if (result.ToString() == "0") // { // //建立新表 // context.Database.ExecuteSqlRaw(str[1]); // } // } // //context.Database.EnsureCreated(); // context.Tests.Add(new Test { Title = "22", Content = $"222 {datetime2}", CreateDateTime = datetime2 }); // context.SaveChanges(); //} //using (var context = new DynamicContext { CreateDateTime = datetime1 }) //{ // var entity = context.Tests.Single(); // // Writes news of today // Console.WriteLine($"{entity.Title} {entity.Content} {entity.CreateDateTime}"); //} //using (var context = new DynamicContext { CreateDateTime = datetime2 }) //{ // var entity = context.Tests.Single(); // // Writes news of yesterday // Console.WriteLine($"{entity.Title} {entity.Content} {entity.CreateDateTime}"); //} #endregion } #region Database資料庫操作 private static string[] GetMySQLSqls(DateTime time) { string tableName = time.ToString("yyyyMMdd"); string decide = $"SELECT count(1) FROM information_schema.TABLES WHERE table_name='{tableName}'"; string sqlRaw = $@" CREATE TABLE IF NOT EXISTS `{tableName}` ( `Id` int(20) NOT NULL, `Title` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `Content` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL, `CreateDateTime` datetime(6) NOT NULL, PRIMARY KEY (`Id`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; "; return new string[] { decide, sqlRaw }; } private static string[] GetSqlServerSqls(DateTime time) { //注意:[Id] int NOT NULL IDENTITY(1,1)中的 IDENTITY(1,1) 表示自增 string tableName = time.ToString("yyyyMMdd"); //-- 判斷要建立的表名是否存在 select * from dbo.sysobjects where id=object_id(N'[dbo].[{0}]') and xtype='U' string decide = $"SELECT COUNT(1) FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[{tableName}]') and OBJECTPROPERTY(id, N'IsUserTable') = 1"; string sqlRaw = $@"IF NOT EXISTS ( SELECT * FROM dbo.sysobjects WHERE id=object_id(N'[dbo].[{tableName}]') AND xtype='U') BEGIN CREATE TABLE [dbo].[{tableName}] ( [Id] int NOT NULL IDENTITY(1,1), [Title] nvarchar(20) NULL , [Content] nvarchar(500) NULL , [CreateDateTime] datetime2(7) NOT NULL , ); ALTER TABLE [dbo].[{tableName}] ADD PRIMARY KEY ([Id]); END"; return new string[] { decide, sqlRaw }; } private static string[] GetOracleSqls(string defaultSchema, DateTime time) { string tableName = time.ToString("yyyyMMdd"); string schema = defaultSchema; string id_seq = $"{tableName}_id_seq"; var pk = $"PK_{tableName}"; string decide = $"SELECT COUNT(1) FROM all_tables WHERE TABLE_NAME='{tableName}' AND OWNER='{schema}'"; string sqlRaw = $@"DECLARE num NUMBER; BEGIN SELECT COUNT(1) INTO num FROM all_tables WHERE TABLE_NAME = '{tableName}' AND OWNER = '{schema}'; IF num = 0 THEN EXECUTE IMMEDIATE 'CREATE TABLE ""{schema}"".""{tableName}"" ( ""Id"" NUMBER(10) NOT NULL, ""Title"" NVARCHAR2(20), ""Content"" NCLOB, ""CreateDateTime"" TIMESTAMP(7) NOT NULL, CONSTRAINT ""{pk}"" PRIMARY KEY(""Id""), )'; EXECUTE IMMEDIATE 'CREATE SEQUENCE ""{schema}"".""{id_seq}"" START WITH 1 INCREMENT BY 1'; END IF; END; "; return new string[] { decide, sqlRaw }; } #endregion #endregion } public class Test { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public DateTime CreateDateTime { get; set; } } public class DynamicContext : DbContext { public DateTime CreateDateTime { get; set; }//為了區分不同的表 public DbSet<Test> Tests { get; set; } //sqlserver連線字串 Server=(localdb)\\mssqllocaldb;Database=DynamicContext;Trusted_Connection=True; //sqlserver連線字串 server=127.0.0.1;database=DynamicContext;user=zy;password=zy; //oracle連線字串 Data Source=127.0.0.1:1521/orcl;User Id=zy;Password=zy; //"DbConnectString": "Data Source=127.0.0.1:1521/orcl;User Id=zy;Password=zy;", //"DefaultSchema": "ZY", //"DbVersion": "11", //mysql連線字串 server=127.0.0.1;database=DynamicContext;user=zy;password=zy; //public static string DbConnectString = "(localdb)\\mssqllocaldb;Database=DynamicContext;Trusted_Connection=True;"; //如果是oracle的話,Oracle連線字串中並不包含資料名稱,其實DefaultSchema就是資料庫名稱,音系需要下面的兩個DefaultSchema,DbVersion欄位 public static string DefaultSchema = "ZY";// public static string DbVersion = "11"; DbType dbType = DbType.SqlServer; #region OnConfiguring protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { switch (dbType) { case DbType.SqlServer: string DbConnectStringSqlServer = "(localdb)\\mssqllocaldb;Database=DynamicContext;Trusted_Connection=True;"; DbConnectStringSqlServer = "server=127.0.0.1;database=DynamicContext;user=zy;password=zy;"; DbConnectStringSqlServer = "server=127.0.0.1;database=DynamicContext;user=sa;password=sa123;"; optionsBuilder.UseSqlServer(DbConnectStringSqlServer) .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); break; case DbType.MySql: string DbConnectStringMySql = "server=127.0.0.1;database=DynamicContext;user=zy;password=zy;"; DbConnectStringMySql = "server=127.0.0.1;database=DynamicContext;user=root;password=123456;"; optionsBuilder.UseMySql(DbConnectStringMySql) .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); break; case DbType.Oracle: string DbConnectStringOracle = "Data Source=127.0.0.1:1521/orcl;User Id=zy;Password=zy;"; optionsBuilder.UseOracle(DbConnectStringOracle, t => t.UseOracleSQLCompatibility(DbVersion)) .ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); break; default: throw new Exception("資料庫不匹配。。。"); } } //=> optionsBuilder.UseMySql(DbConnectString).ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); //=> optionsBuilder.UseOracle(DbConnectString).ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); //=> optionsBuilder.UseSqlServer(DbConnectString).ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); //protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) //=> optionsBuilder.UseInMemoryDatabase("DynamicContext") //.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>(); #endregion #region OnModelCreating protected override void OnModelCreating(ModelBuilder modelBuilder) { if (Database.IsOracle()) { modelBuilder.HasDefaultSchema(DefaultSchema); } modelBuilder.Entity<Test>(b => { b.ToTable(CreateDateTime.ToString("yyyyMMdd")); b.HasKey(p => p.Id); //b.Property(p => p.Id).HasColumnType("int").ValueGeneratedOnAdd(); //b.Property(p => p.Id).HasColumnType("int"); b.Property(p => p.Title).HasMaxLength(20); b.Property(p => p.Content).HasMaxLength(500); }); } #endregion } public enum DbType { SqlServer, MySql, Oracle } public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory { public object Create(DbContext context) => context is DynamicContext dynamicContext ? (context.GetType(), dynamicContext.CreateDateTime) : (object)context.GetType(); } }
龍騰一族至尊龍騎