Sqlit Dapper根据模型新建表

发布于:2025-09-04 ⋅ 阅读:(20) ⋅ 点赞:(0)

有key:

using var con = new SQLiteConnection(Connection);
CreateTableHasKey<模型名称>(con, 表名称);//创建表

 private string GetColumnType(PropertyInfo property)
        {
            Type propertyType = property.PropertyType;

            if (propertyType == typeof(int) || propertyType == typeof(int?))
            {
                return "INTEGER";
            }
            else if (propertyType == typeof(string) || propertyType == typeof(decimal) || propertyType == typeof(decimal?))
            {
                return "TEXT";
            }
            else if (propertyType == typeof(double) || propertyType == typeof(double?) || propertyType == typeof(float))
            {
                return "DOUBLE";
            }
            else if (propertyType == typeof(bool))
            {
                return "REAL";
            }
            else if (propertyType == typeof(byte[]))
            {
                return "BLOB";
            }
            else
            {
                throw new NotSupportedException("Column type not supported.");
            }
        }


        /// <summary>
        /// 新建表 有主键
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="tableName"></param>
        public void CreateTableHasKey<T>(SQLiteConnection connection, string tableName)
        {
            try
            {
                var properties = typeof(T).GetProperties().Where(p => Attribute.IsDefined(p, typeof(IgnoreFieldAttribute)) == false);
                var queryString = new StringBuilder("CREATE TABLE IF NOT EXISTS ");
                queryString.Append($"{tableName}");
                queryString.Append(" (");
                int i = 0;
                foreach (var property in properties)
                {
                    string columnName = property.Name;
                    string columnType = GetColumnType(property);
                    // 处理 ID 属性
                    if (columnName == "ID" && property.PropertyType == typeof(int))  // int
                    {
                        columnType += " PRIMARY KEY AUTOINCREMENT";
                    }
                    else if (columnName == "ID" && property.PropertyType == typeof(int?))  // int?
                    {
                        columnType += " PRIMARY KEY"; // 这里不再使用 AUTOINCREMENT,通常主键应该是自增的
                    }
                    else if (columnName == "Guid")
                    {
                        columnType += " PRIMARY KEY";
                    }

                    queryString.Append(columnName);
                    queryString.Append(' ');
                    queryString.Append(columnType);
                    columnName = null;
                    columnType = null;
                    if (i < properties.Count() - 1)
                    {
                        queryString.Append(", ");
                    }
                    i++;
                }

                queryString.Append(" )");
                connection.Execute(queryString.ToString());
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

没有key:
 


        /// <summary>
        /// 新建表 没主键
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="connection"></param>
        /// <param name="tableName"></param>
        public void CreateTable<T>(SQLiteConnection connection, string tableName)
        {
            try
            {
                var properties = typeof(T).GetProperties().Where(p => Attribute.IsDefined(p, typeof(IgnoreFieldAttribute)) == false);

                var queryString = new StringBuilder("CREATE TABLE IF NOT EXISTS ");
                queryString.Append($"{tableName}");
                queryString.Append(" (");

                int i = 0;
                foreach (var property in properties)
                {
                    string columnName = property.Name;
                    string columnType = GetColumnType(property);
                    queryString.Append(columnName);
                    queryString.Append(' ');
                    queryString.Append(columnType);
                    columnName = null;
                    columnType = null;

                    if (i < properties.Count() - 1)
                    {
                        queryString.Append(", ");
                    }
                    i++;
                }

                queryString.Append(')');
                connection.Execute(queryString.ToString());

                var columns = connection.Query($"PRAGMA table_info({tableName})");

                // 检查返回结果中是否存在主键列
                bool hasPrimaryKey = columns.Any(column => column.pk == 1);
                if (hasPrimaryKey)
                {
                    // 创建临时表
                    connection.Execute($"CREATE TABLE TempTable AS SELECT * FROM {tableName}");

                    // 删除原始表
                    connection.Execute($"DROP TABLE {tableName}");

                    // 重新创建原始表(不包含主键约束)
                    CreateTable<T>(connection, tableName);

                    // 将临时表的数据插入到重新创建的原始表中
                    connection.Execute($"INSERT INTO {tableName} SELECT * FROM TempTable");

                    // 删除临时表
                    connection.Execute("DROP TABLE TempTable");
                }
                columns = null;
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }


        private string GetColumnType(PropertyInfo property)
        {
            Type propertyType = property.PropertyType;

            if (propertyType == typeof(int) || propertyType == typeof(int?))
            {
                return "INTEGER";
            }
            else if (propertyType == typeof(string) || propertyType == typeof(decimal) || propertyType == typeof(decimal?))
            {
                return "TEXT";
            }
            else if (propertyType == typeof(double) || propertyType == typeof(double?) || propertyType == typeof(float))
            {
                return "DOUBLE";
            }
            else if (propertyType == typeof(bool))
            {
                return "REAL";
            }
            else if (propertyType == typeof(byte[]))
            {
                return "BLOB";
            }
            else
            {
                throw new NotSupportedException("Column type not supported.");
            }
        }

     PS:如果模型中有不需要加到数据库中的字段则加标记。如下代码所示:

  

 public partial class UserInfoModel : ObservableObject
    {
        public UserInfoModel() { }

        [ObservableProperty]
        string _Guid;

        /// <summary>
        /// 用户名
        /// </summary>
        [ObservableProperty]
        string _Name;

        /// <summary>
        /// 创建人
        /// </summary>
        [ObservableProperty]
        string _Creater;

        /// <summary>
        /// 创建时间
        /// </summary>
        [ObservableProperty]
        string _CreateTime;


        /// <summary>
        /// 备注
        /// </summary>
        [ObservableProperty]
        string _Remark;

        #region 本地字段

        string _StateStr;
        [IgnoreField]
        public string StateStr { get => _StateStr; set => SetProperty(ref _StateStr, value); }
        #endregion
    }

表中增加数据,可写成公用方法如下:

 /// <summary>
        /// 插入sql的公用方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tableName"></param>
        /// <returns></returns>
        private string GenerateInsertQuery<T>(string tableName)
        {
            // 检查属性是否标记为忽略字段
            var propertyNames = typeof(T).GetProperties().Where(p => Attribute.IsDefined(p, typeof(IgnoreFieldAttribute)) == false).Select(p => p.Name);
            var columnNames = string.Join(", ", propertyNames);
            var parameterNames = string.Join(", ", propertyNames.Select(p => $"@{p}"));
            var insertQuery = $"INSERT INTO {tableName} ({columnNames}) VALUES ({parameterNames})";
            return insertQuery;
        }

        /// <summary>
        /// 新增数据 
        /// </summary>
        /// <returns></returns>
        public void InsertTable(模型 model)
        {
            if (model == null) { return; }
            try
            {
                using var connew = new SQLiteConnection(Connection);
                if (connew.State == ConnectionState.Closed) { connew.Open(); }
                var tran = connew.BeginTransaction(IsolationLevel.Serializable);//开启事务
                try
                {
                    connew.Execute("Delete from XXXTable where Guid=@InGuid;", new { InGuid = model.Guid }, transaction: tran);
                    connew.Execute(GenerateInsertQuery<模型名称>("XXXTable"), model, transaction: tran);
                    tran.Commit();
                    model = null;
                }
                catch (Exception)
                {
                    tran.Rollback();
                    throw;
                }
            }
            catch (Exception ex)
            {
                LogHelper.GetSingleObj().WriteLog(ex);
            }
        }

这样模型中也可写表不用的字段,用来数据绑定等其他用途。还可以做成公用方法便于调用和利用。


网站公告

今日签到

点亮在社区的每一天
去签到