RHDWContext.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. using SQLite.CodeFirst;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel.DataAnnotations.Schema;
  5. using System.Data.Common;
  6. using System.Data.Entity;
  7. using System.Data.Entity.Core.Common;
  8. using System.Data.Entity.Core.Metadata.Edm;
  9. using System.Data.Entity.Infrastructure;
  10. using System.Data.Entity.Infrastructure.Interception;
  11. using System.Data.Entity.ModelConfiguration.Conventions;
  12. using System.Data.Entity.Validation;
  13. using System.Data.SQLite;
  14. using System.Data.SQLite.EF6;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Reflection;
  18. using System.Text;
  19. using System.Text.RegularExpressions;
  20. using System.Threading.Tasks;
  21. using XdCxRhDW.Entity;
  22. namespace XdCxRhDW.Repostory
  23. {
  24. class DbTableColumnInfo
  25. {
  26. public string name { get; set; }
  27. public string type { get; set; }
  28. public int notnull { get; set; }
  29. public int pk { get; set; }
  30. }
  31. public class DbContextBase : DbContext
  32. {
  33. public DbContextBase(string nameOrConnectionString)
  34. : base(nameOrConnectionString)
  35. {
  36. }
  37. public void SyncDb()
  38. {
  39. SyncTable();
  40. SyncTableField();
  41. }
  42. void SyncTable()
  43. {
  44. var tables = this.Database.SqlQuery<string>("select name from sqlite_master where type='table' and name not like 'sqlite%'").ToList();
  45. var props = this.GetType().GetProperties();
  46. Dictionary<string, Type> list = new Dictionary<string, Type>();
  47. foreach (var prop in props)
  48. {
  49. bool isDbSet = prop.PropertyType.IsGenericType && typeof(DbSet<>) == prop.PropertyType.GetGenericTypeDefinition();
  50. if (isDbSet)
  51. {
  52. var entityType = prop.PropertyType.GenericTypeArguments[0];
  53. var name = entityType.GetCustomAttribute<TableAttribute>()?.Name;
  54. if (name == null)
  55. {
  56. name = entityType.Name;
  57. }
  58. list.Add(name, entityType);
  59. }
  60. }
  61. foreach (var item in list)
  62. {
  63. if (!tables.Contains(item.Key))
  64. {
  65. var entityProps = item.Value.GetProperties().Where(p =>
  66. p.CanRead
  67. && p.CanWrite
  68. && !p.GetMethod.IsVirtual
  69. && p.GetCustomAttribute<NotMappedAttribute>() == null);
  70. item.Value.GetProperties().Where(p => p.CanWrite);
  71. StringBuilder sb = new StringBuilder();
  72. sb.Append($"create table {item.Key}(ID integer primary key autoincrement");
  73. foreach (var prop in entityProps)
  74. {
  75. if (prop.Name.ToLower() == "id") continue;
  76. bool isNullable = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
  77. string typeStr = "";
  78. var type = prop.PropertyType;
  79. if (prop.PropertyType.IsGenericType)
  80. {
  81. type = prop.PropertyType.GenericTypeArguments[0];
  82. }
  83. if (type == typeof(string))
  84. {
  85. typeStr = "nvarchar";
  86. }
  87. else if (type == typeof(int) || type == typeof(long) || prop.PropertyType.IsEnum)
  88. {
  89. typeStr = "int";
  90. }
  91. else if (type == typeof(double) || type == typeof(float))
  92. {
  93. typeStr = "float";
  94. }
  95. else if (type == typeof(DateTime))
  96. {
  97. typeStr = "datetime";
  98. }
  99. sb.Append($",{prop.Name} {typeStr}");
  100. if (!isNullable)
  101. {
  102. sb.Append(" not null");
  103. }
  104. }
  105. sb.Append(")");
  106. string createTableSql = sb.ToString();
  107. Database.ExecuteSqlCommand(createTableSql);
  108. }
  109. }
  110. }
  111. void SyncTableField()
  112. {
  113. var tables = this.Database.SqlQuery<string>("select name from sqlite_master where type='table' and name not like 'sqlite%'").ToList();
  114. var props = this.GetType().GetProperties();
  115. List<Type> entityTypes = new List<Type>();
  116. foreach (var prop in props)
  117. {
  118. bool isDbSet = prop.PropertyType.IsGenericType && typeof(DbSet<>) == prop.PropertyType.GetGenericTypeDefinition();
  119. if (isDbSet)
  120. {
  121. var entityType = prop.PropertyType.GenericTypeArguments[0];
  122. entityTypes.Add(entityType);
  123. }
  124. }
  125. foreach (var table in tables)
  126. {
  127. var res = this.Database.SqlQuery<DbTableColumnInfo>($"PRAGMA table_info([{table}])").ToList();
  128. var entityType = entityTypes.FirstOrDefault(p => p.Name == table);
  129. if (entityType == null) continue;
  130. var entityProps = entityType.GetProperties().Where(p =>
  131. p.CanRead
  132. && p.CanWrite
  133. && !p.GetMethod.IsVirtual
  134. && p.GetCustomAttribute<NotMappedAttribute>() == null);
  135. foreach (var prop in entityProps)
  136. {
  137. var find = res.Find(p => p.name.ToLower() == prop.Name.ToLower());
  138. if (find == null)
  139. {
  140. string typeStr = "";
  141. var type = prop.PropertyType;
  142. if (prop.PropertyType.IsGenericType)
  143. {
  144. type = prop.PropertyType.GenericTypeArguments[0];
  145. }
  146. if (type == typeof(string))
  147. {
  148. typeStr = "nvarchar";
  149. }
  150. else if (type == typeof(int) || type == typeof(long) || prop.PropertyType.IsEnum)
  151. {
  152. typeStr = "int";
  153. }
  154. else if (type == typeof(double) || type == typeof(float))
  155. {
  156. typeStr = "float";
  157. }
  158. else if (type == typeof(DateTime))
  159. {
  160. typeStr = "datetime";
  161. }
  162. bool isNullable = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
  163. string updateTableSql;
  164. if (isNullable)
  165. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr}";
  166. else
  167. {
  168. if (typeStr == "int" || typeStr == "float")
  169. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default 0";
  170. else if (typeStr == "nvarchar")
  171. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default ''";
  172. else if (typeStr == "datetime")
  173. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default '{DateTime.Now:yyyy-MM-dd HH:mm:ss}'";
  174. else
  175. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr}";
  176. }
  177. this.Database.ExecuteSqlCommand(updateTableSql);
  178. }
  179. }
  180. }
  181. }
  182. }
  183. public class RHDWLogContext : DbContextBase
  184. {
  185. public string DbFile;
  186. public RHDWLogContext() : base("LogDbCon") //配置使用的连接名
  187. {
  188. //|DataDirectory|在mvc等程序中代表了App_Data,在普通程序中代表程序根目录
  189. var dbFile = Database.Connection.ConnectionString.Replace("Data Source=", "").Replace("|DataDirectory|\\", "");
  190. this.DbFile = dbFile;
  191. }
  192. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  193. {
  194. this.Database.Log = msg =>
  195. {
  196. };
  197. modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
  198. modelBuilder.Configurations.AddFromAssembly(typeof(RHDWLogContext).Assembly);//自动加载Entity-Type
  199. var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<RHDWLogContext>(modelBuilder);
  200. Database.SetInitializer(sqliteConnectionInitializer);
  201. base.OnModelCreating(modelBuilder);
  202. }
  203. public DbSet<LogRes> LogRes { set; get; }
  204. }
  205. /// <summary>
  206. /// 基础表上下文(id为int)
  207. /// </summary>
  208. public class RHDWContext : DbContextBase
  209. {
  210. public string DbFile;
  211. public RHDWContext() : base("DbCon") //配置使用的连接名
  212. {
  213. //|DataDirectory|在mvc等程序中代表了App_Data,在普通程序中代表程序根目录
  214. this.DbFile = Database.Connection.ConnectionString.Replace("Data Source=", "").Replace("|DataDirectory|\\", "");
  215. }
  216. public Task<List<T>> SqlQueryAsync<T>(string sql)
  217. {
  218. return this.Database.SqlQuery<T>(sql).ToListAsync();
  219. }
  220. public Task<T> SqlQueryOneAsync<T>(string sql)
  221. {
  222. return this.Database.SqlQuery<T>(sql).FirstOrDefaultAsync();
  223. }
  224. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  225. {
  226. this.Database.Log = msg =>
  227. {
  228. };
  229. modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
  230. modelBuilder.Configurations.AddFromAssembly(typeof(RHDWContext).Assembly);//自动加载Entity-Type
  231. var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<RHDWContext>(modelBuilder);
  232. Database.SetInitializer(sqliteConnectionInitializer);
  233. base.OnModelCreating(modelBuilder);
  234. }
  235. public DbSet<XlInfo> XlInfos { set; get; }
  236. public DbSet<TaskInfo> TaskInfos { set; get; }
  237. public DbSet<TaskSig> TaskSigs { set; get; }
  238. public DbSet<TxInfo> TxInfos { get; set; }
  239. public DbSet<SatInfo> SatInfos { get; set; }
  240. public DbSet<FixedStation> FixedStation { get; set; }
  241. public DbSet<SigInfo> SigInfos { get; set; }
  242. public DbSet<SigDelay> SigDelays { get; set; }
  243. public DbSet<TargetInfo> TargetInfos { get; set; }
  244. public DbSet<SysSetings> SysSetings { get; set; }
  245. public DbSet<TaskRunnningInfo> TaskRunnningInfos { get; set; }
  246. }
  247. /// <summary>
  248. /// 分区表上下文(id为long)
  249. /// </summary>
  250. public class RHDWPartContext : DbContext
  251. {
  252. private string DbFile;
  253. public static RHDWPartContext GetContext(string dbFile, bool createDb = false)
  254. {
  255. if (!File.Exists(dbFile) && !createDb)
  256. {
  257. return null;
  258. }
  259. var connectionString = $@"Data Source={dbFile}";
  260. SQLiteConnection con = new SQLiteConnection(connectionString);
  261. return new RHDWPartContext(con);
  262. }
  263. public static RHDWPartContext GetContext(DateTime partTime, bool createDb = false, string prefix = "")
  264. {
  265. var dir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DbPart");
  266. var dayFile = Path.Combine(dir, $@"{partTime.Year}\{prefix}{partTime:MMdd}.db");
  267. if (!File.Exists(dayFile) && !createDb)
  268. {
  269. return null;
  270. }
  271. var connectionString = $@"Data Source=|DataDirectory|\DbPart\{partTime.Year}\{prefix}{partTime:MMdd}.db";
  272. SQLiteConnection con = new SQLiteConnection(connectionString);
  273. return new RHDWPartContext(con);
  274. }
  275. private RHDWPartContext(DbConnection con)
  276. : base(con, true)
  277. {
  278. var dbFile = Database.Connection.ConnectionString.Replace("Data Source=", "").Replace("|DataDirectory|\\", "");
  279. this.DbFile = dbFile;
  280. }
  281. public bool IsTableFieldSync()
  282. {
  283. bool val = true;
  284. var tables = this.Database.SqlQuery<string>("select name from sqlite_master where type='table' and name not like 'sqlite%'").ToList();
  285. var props = this.GetType().GetProperties();
  286. List<Type> entityTypes = new List<Type>();
  287. foreach (var prop in props)
  288. {
  289. bool isDbSet = prop.PropertyType.IsGenericType && typeof(DbSet<>) == prop.PropertyType.GetGenericTypeDefinition();
  290. if (isDbSet)
  291. {
  292. var entityType = prop.PropertyType.GenericTypeArguments[0];
  293. entityTypes.Add(entityType);
  294. }
  295. }
  296. foreach (var table in tables)
  297. {
  298. var res = this.Database.SqlQuery<DbTableColumnInfo>($"PRAGMA table_info([{table}])").ToList();
  299. var entityType = entityTypes.FirstOrDefault(p => p.Name == table);
  300. if (entityType == null) continue;
  301. var entityProps = entityType.GetProperties().Where(p =>
  302. p.CanRead
  303. && p.CanWrite
  304. && !p.GetMethod.IsVirtual
  305. && p.GetCustomAttribute<NotMappedAttribute>() == null);
  306. foreach (var prop in entityProps)
  307. {
  308. var find = res.Find(p => p.name.ToLower() == prop.Name.ToLower());
  309. if (find == null)
  310. {
  311. string typeStr = "";
  312. var type = prop.PropertyType;
  313. if (prop.PropertyType.IsGenericType)
  314. {
  315. type = prop.PropertyType.GenericTypeArguments[0];
  316. }
  317. if (type == typeof(string))
  318. {
  319. typeStr = "nvarchar";
  320. }
  321. else if (type == typeof(int) || type == typeof(long) || prop.PropertyType.IsEnum)
  322. {
  323. typeStr = "int";
  324. }
  325. else if (type == typeof(double) || type == typeof(float))
  326. {
  327. typeStr = "float";
  328. }
  329. else if (type == typeof(DateTime))
  330. {
  331. typeStr = "datetime";
  332. }
  333. bool isNullable = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
  334. string updateTableSql;
  335. if (isNullable)
  336. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr}";
  337. else
  338. {
  339. if (typeStr == "int" || typeStr == "float")
  340. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default 0";
  341. else if (typeStr == "nvarchar")
  342. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default ''";
  343. else if (typeStr == "datetime")
  344. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr} not null default '{DateTime.Now:yyyy-MM-dd HH:mm:ss}'";
  345. else
  346. updateTableSql = $"alter table {table} add column {prop.Name} {typeStr}";
  347. }
  348. this.Database.ExecuteSqlCommand(updateTableSql);
  349. val = false;
  350. }
  351. }
  352. }
  353. return val;
  354. }
  355. protected override void OnModelCreating(DbModelBuilder modelBuilder)
  356. {
  357. this.Database.Log = msg =>
  358. {
  359. };
  360. modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
  361. modelBuilder.Configurations.AddFromAssembly(typeof(RHDWPartContext).Assembly);
  362. var sqliteConnectionInitializer = new SqliteCreateDatabaseIfNotExists<RHDWPartContext>(modelBuilder);
  363. Database.SetInitializer(sqliteConnectionInitializer);
  364. base.OnModelCreating(modelBuilder);
  365. }
  366. public DbSet<StationRes> StationRes { get; set; }
  367. public DbSet<CxRes> CxRes { get; set; }
  368. public DbSet<CgRes> CgRes { get; set; }
  369. public DbSet<CgXgfRes> CgXgfRes { get; set; }
  370. public DbSet<PosRes> PosRes { get; set; }
  371. public DbSet<CheckRes> CheckRes { get; set; }
  372. }
  373. public class SqliteConfiguration : DbConfiguration
  374. {
  375. public SqliteConfiguration()
  376. {
  377. DbInterception.Add(new SqliteInterceptor());//拦截器
  378. SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);
  379. SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance);
  380. SetProviderServices("System.Data.SQLite", (DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices)));
  381. }
  382. }
  383. }