示例实体:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Diagnostics.CodeAnalysis;
using Honeysuckle.Domain.Entities; namespace Chagoi.Pos.Core.Entity.Goods
{
[Table("a2")]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public class GoodsInfo : Entity<int>
{
[Column("c1")]
public string Name { get; set; } /// <summary>
/// 商品条码
/// </summary>
[Column("c2")]
[StringLength()]
[Index]
public string goods_barcode { get; set; } /// <summary>
/// 简称
/// </summary>
[Column("c3")]
[StringLength()]
[Index("fdafd")]
public string goods_short_name { get; set; } [Column("c4")]
[StringLength()]
[Required]
public string hello { get; set; } [Column("c5")]
public DateTime UpdateTime { get; set; }
} }

生成代码:

using Castle.Core.Logging;
using Chagoi.Pos.Core.Entity.Device;
using Chagoi.Pos.Core.Entity.Goods;
using Chagoi.Pos.Core.Entity.Order;
using Chagoi.Pos.Core.Entity.Pay;
using Chagoi.Pos.Core.Entity.Users;
using Honeysuckle.Dependency;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Configuration;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;
using System.Linq;
using System.Text; namespace Chagoi.Pos.EntityFramework.Seed
{
public static class SeedHelper
{
private static readonly string DbPath;
private static ILogger _logger; static SeedHelper()
{
DbPath = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
} public static void SeedHostDb(IIocResolver iocResolver, ILogger logger)
{
_logger = logger;
SeedHostDb();
} private static void SeedHostDb()
{
var tobeCreateTables = new List<Type>()
{
typeof(IotDevice), typeof(GoodsInfo),
typeof(GoodsCategory),
typeof(GoodsBrand), typeof(AlipayParameter),
typeof(WxpayParameter), typeof(AppUser),
typeof(Order)
}; _logger.Info("#region 开始执行数据库的创建或结构调整"); var stopwatch = new Stopwatch();
stopwatch.Start(); using (var connection = new SQLiteConnection(DbPath))
{
connection.Open(); using (var transaction = connection.BeginTransaction())
{
try
{
foreach (var entity in tobeCreateTables)
{
//表名称,这里使用混淆表明,要求必须输入
var tableAttribute = entity.GetCustomAttributes(typeof(TableAttribute), true).FirstOrDefault();
if (null == tableAttribute)
{
throw new ArgumentNullException(nameof(TableAttribute));
}
var tableName = ((TableAttribute)tableAttribute).Name; //填充数据库中标的原始结构
var tableStructureCommandText = $"PRAGMA table_info(\"{tableName}\");";
var sqLiteCommand = new SQLiteCommand(connection) { CommandText = tableStructureCommandText };
var sQLiteDataAdapter = new SQLiteDataAdapter(sqLiteCommand);
var tableStructure = new DataTable(tableName);
sQLiteDataAdapter.Fill(tableStructure); var hasTable = tableStructure.Rows.Count > ;
if (!hasTable)
{
_logger.Info($"表{tableName}不存在,开始执行创建过程..."); //执行创建表的SQL语句
var createTableSql = GenerateCreateTableCommandText(entity, tableName);
sqLiteCommand.CommandText = createTableSql;
_logger.Debug(sqLiteCommand.CommandText);
sqLiteCommand.ExecuteNonQuery();
_logger.Info($"表{tableName}的创建语句已执行.");
}
else
{
_logger.Info($"表{tableName}已经存在,开始执行差异对比过程...");
var updateTableSql = GenerateUpdateTableCommandText(entity, tableStructure);
if (string.IsNullOrEmpty(updateTableSql))
{
_logger.Info($"表{tableName}结构无差异,无需调整.");
continue;
}
sqLiteCommand.CommandText = updateTableSql;
_logger.Debug(sqLiteCommand.CommandText);
var nonQuery = sqLiteCommand.ExecuteNonQuery();
_logger.Info($"表{tableName}的调整语句已执行,返回结果:{nonQuery}");
}
} transaction.Commit();
}
catch (Exception ex)
{
_logger.Error("执行数据库的创建或结构调整过程发生异常",ex);
transaction.Rollback();
}
} connection.Dispose();
} stopwatch.Stop(); var elapsedMilliseconds = stopwatch.ElapsedMilliseconds; _logger.Info($"#endregion 执行数据库的创建或结构调整过程完毕,耗时{elapsedMilliseconds}毫秒");
} /// <summary>
/// 生成创建表的sql命令,包含索引的创建
/// </summary>
/// <param name="entityType">实体类型</param>
/// <param name="tableName">表的名称</param>
/// <returns></returns>
private static string GenerateCreateTableCommandText(Type entityType, string tableName)
{
var properties = entityType.GetProperties(); //索引创建语句,根据实体的Index特性来生成
var createTableIndexCommandTexts = new List<string>(); var createTableCommandText = $"CREATE TABLE \"{tableName}\" (";
foreach (var property in properties)
{
//列名,优先取特性名称
var columnName = GetColumnName(property); //是否可空
var notNull = IsNotNull(property); //字段类型
var dbType = GetDbType(property); createTableCommandText += $"\"{columnName}\" {dbType} {notNull},"; //处理索引
var indexAttributeObj = property.GetCustomAttributes(typeof(IndexAttribute), true).FirstOrDefault();
if (null != indexAttributeObj)
{
var indexAttribute = ((IndexAttribute)indexAttributeObj); //是否是唯一索引
var unique = indexAttribute.IsUnique ? "UNIQUE" : ""; //索引名称
var indexName = string.IsNullOrEmpty(indexAttribute.Name) ? $"Index_{columnName}" : indexAttribute.Name; //创建索引的语句
var indexSql = $"CREATE {unique} INDEX \"{indexName}\" ON \"{tableName}\"(\"{columnName}\" ASC); ";
createTableIndexCommandTexts.Add(indexSql);
}
}
createTableCommandText += "PRIMARY KEY (\"Id\" ASC)";
createTableCommandText += ");"; var allCommandText = new StringBuilder(createTableCommandText);
foreach (var createTableIndexCommandText in createTableIndexCommandTexts)
{
allCommandText.Append(createTableIndexCommandText);
}
return allCommandText.ToString();
} /// <summary>
/// 生成更新表的sql命令,只支持新增列
/// 不支持添加索引列,不支持删除列
/// 新增的列必须允许为空
/// </summary>
/// <param name="entityType">实体类型</param>
/// <param name="dataTable">数据中的表结构</param>
/// <returns></returns>
private static string GenerateUpdateTableCommandText(Type entityType, DataTable dataTable)
{
var properties = entityType.GetProperties();
var alreadyCreatedColumnNames = dataTable.AsEnumerable().Select(t => t.Field<string>("name").ToString()).ToArray(); var addColumnCommandTexts = new List<string>();
foreach (var property in properties)
{
var colName = GetColumnName(property);
var alreadyCreated = alreadyCreatedColumnNames.Any(m => m == colName);
if (!alreadyCreated)
{ var dbType = GetDbType(property);
var addColumnCommandText = $"ALTER TABLE \"{dataTable.TableName}\" ADD COLUMN \"{colName}\" {dbType} NULL;";
addColumnCommandTexts.Add(addColumnCommandText);
}
} var allCommandText = new StringBuilder();
foreach (var addColumnCommand in addColumnCommandTexts)
{
allCommandText.Append(addColumnCommand);
}
return allCommandText.ToString();
} #region 基础函数 /// <summary>
/// 获取数据类型
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
private static string GetDbType(System.Reflection.PropertyInfo property)
{
string dbType;
if (property.PropertyType.FullName != null)
{
var propertyTypeFullName = property.PropertyType.FullName.ToUpper();
switch (propertyTypeFullName)
{
case "SYSTEM.BOOLEAN":
dbType = "BOOLEAN";
break;
case "SYSTEM.INT32":
case "SYSTEM.INT64":
dbType = "INTEGER";
break;
case "SYSTEM.STRING":
//是否标记了最大长度
var stringLengthAttributeObj = property.GetCustomAttributes(typeof(StringLengthAttribute), true).FirstOrDefault();
if (stringLengthAttributeObj != null)
{
var length = ((StringLengthAttribute)stringLengthAttributeObj).MaximumLength;
dbType = $"VARCHAR({length})";
}
else
{
dbType = "TEXT";
}
break;
case "SYSTEM.DATETIME":
dbType = "DATETIME";
break;
default:
throw new ArgumentOutOfRangeException(nameof(propertyTypeFullName));
}
}
else
{
throw new ArgumentNullException(nameof(property.PropertyType.FullName));
} return dbType;
} /// <summary>
/// 字段是否可用
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
private static string IsNotNull(System.Reflection.PropertyInfo property)
{
var hasRequiredAttribute = property.GetCustomAttributes(typeof(RequiredAttribute), true).Length > ;
var notNull = hasRequiredAttribute ? "NOT NULL" : "";
if (property.Name.ToUpper() == "ID") //ID始终不能为空
{
notNull = "NOT NULL";
} return notNull;
} /// <summary>
/// 获取列名
/// </summary>
/// <param name="property"></param>
/// <returns></returns>
private static string GetColumnName(System.Reflection.PropertyInfo property)
{
var columnName = property.Name;
var columnAttributeObj = property.GetCustomAttributes(typeof(ColumnAttribute), true).FirstOrDefault();
if (null != columnAttributeObj)
{
columnName = ((ColumnAttribute)columnAttributeObj).Name;
} return columnName;
} #endregion
}
}

Sqlite CodeFirst的初级实现的更多相关文章

  1. EntityFramework系列:SQLite.CodeFirst自动生成数据库

    http://www.cnblogs.com/easygame/p/4447457.html 在Code First模式下使用SQLite一直存在不能自动生成数据库的问题,使用SQL Server C ...

  2. C#/.NET VS2017+ EF+SQLite.CodeFirst——真正实现CodeFirst

    本文所介绍的是真正的EF+CodeFirst,不需要提前建表,由代码自动生成! 进行前需要准备的: 1.下载Sqlite Experthttp://www.sqliteexpert.com/downl ...

  3. SQLite 的 CodeFirst 模式

    目录 问题描述 解决方案 安装依赖包 修改程序配置 App.config 创建模型对象 Person.cs 创建数据上下文 PersonDbContext.cs 主程序调用 Program.cs 注意 ...

  4. EntityFramework SQLite

    安装完sqlite的nuget包后,还要设置App.config文件才能正常使用 1.  在<providers>节点添加一条提供器配置 <provider invariantNam ...

  5. 通过EntityFramework操作sqlite(DbFirst)

    记录一下通过 EntityFramework6 来操作sqlite过程 环境: visual studio 2017 .net 4.5 Console Application(项目类型) sqlite ...

  6. visual studio 2013 下ef6 CodeFirst 使用SQL Lite 数据库

    今天系统的来记录一下再vs2013下,使用ef6 codefirst功能,来操作SQL lite数据库 本来我以为sqlite数据库用的这么多,ef6肯定支持,结果,使用过程中很多坑,现在我把具体的配 ...

  7. EntityFramework系列:SQLite的CodeFrist和RowVersion

    没什么好说的,能支持DropCreateDatabaseIfModelChanges和RowVersion的Sqlite谁都想要.EntityFramework7正在添加对Sqlite的支持,虽然EF ...

  8. EF6 Code First 系列 (四):SQLite的DropCreateDatabaseIfModelChanges和乐观并发控制

    没什么好说的,能支持DropCreateDatabaseIfModelChanges和RowVersion的Sqlite谁都想要.EntityFramework7正在添加对Sqlite的支持,虽然EF ...

  9. 【C#】使用EF访问Sqlite数据库

    原文:[C#]使用EF访问Sqlite数据库 1. 先上Nuget下载对应的包 如图,搜索System.Data.SQLite下载安装即可,下载完之后带上依赖一共有这么几个: EntityFramew ...

随机推荐

  1. HightCharts开发总结

    1.   简介:Highcharts是一款纯javascript编写的图表库,能够在Web网站或Web应用中添加交互性的图表,现在官方的最新版本为Highcharts-4.2.3. 2.   兼容性: ...

  2. javascript总结10:JavaScript的Switch语句

    1 switch语句 的作用: switch 语句用于基于不同的条件来执行不同的动作. 每当满足一个变量条件,就会执行当前的case内容. break 关键字用于跳出switch代码块.会终止swit ...

  3. 升级Ubuntu 12.04下的gcc到4.7

    我们知道C++11标准开始支持类内初始化(in-class initializer),Qt creator编译出现error,不支持这个特性,原因在于,Ubuntu12.04默认的是使用gcc4.6, ...

  4. 注入学习1:SQL注入语句大全

    学习背景 之前做了xss预防,以及些许的注入预防了,但是不够全面,如果还是搜集了下一些常用的注入手段,以此用来进行更好的预防. 什么是注入 一般来说,SQL注入一般存在于形如:HTTP://xxx.x ...

  5. FractalNet(分形网络)

    -Argues that key is transitioning effectively from shallow to deep and residual representations are ...

  6. 【Java】java中的compareTo和compare的区别

    compare 从这里可以看出,compare是Comparator接口中的一个类,再看一下源代码中的解释 Compares its two arguments for order. Returns ...

  7. ubuntu 下python安装及hello world

    //@desn:ubuntu 下python安装及hello world //@desn:码字不宜,转载请注明出处 //@author:张慧源  <turing_zhy@163.com> ...

  8. 【EfF】 贪婪加载和延迟加载 (virtual去掉关闭延迟加载)

    EntityFramework(EF)贪婪加载和延迟加载的选择和使用 贪婪加载:顾名思议就是把所有要加载的东西一 次性读取 1 using (var context = new MyDbContext ...

  9. CentOS Vi编辑器

    vim:通过vim a.cfg进入文档 i:编辑状态 ESC:返回不可编辑状态 dd:在不可编辑状态下,dd可删除光标所在的行,2dd删除两行,以此类推 u:在不可编辑状态下,u可恢复删除的行 yy: ...

  10. 使用 typescript ,提升 vue 项目的开发体验(1)

    此文已由作者张汉锐授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言:对于我们而言,typescript 更像一个工具 官方指南 从 vue2.5 之后,vue 对 ts ...