Example #1
0
        /// <summary>检查字段改变。某些数据库(如SQLite)没有添删改字段的DDL语法,可重载该方法,使用重建表方法ReBuildTable</summary>
        /// <param name="entitytable"></param>
        /// <param name="dbtable"></param>
        /// <param name="onlySql"></param>
        /// <param name="noDelete"></param>
        /// <returns></returns>
        protected virtual String CheckColumnsChange(IDataTable entitytable, IDataTable dbtable, Boolean onlySql, Boolean noDelete)
        {
            //var onlySql = mode <= Migration.ReadOnly;
            //var noDelete = mode < Migration.Full;

            var sb    = new StringBuilder();
            var etdic = entitytable.Columns.ToDictionary(e => e.ColumnName.ToLower(), e => e, StringComparer.OrdinalIgnoreCase);
            var dbdic = dbtable.Columns.ToDictionary(e => e.ColumnName.ToLower(), e => e, StringComparer.OrdinalIgnoreCase);

            #region 新增列
            foreach (var item in entitytable.Columns)
            {
                if (!dbdic.ContainsKey(item.ColumnName.ToLower()))
                {
                    // 非空字段需要重建表
                    if (!item.Nullable)
                    {
                        //var sql = ReBuildTable(entitytable, dbtable);
                        //if (noDelete)
                        //{
                        //    WriteLog("数据表新增非空字段[{0}],需要重建表,请手工执行:\r\n{1}", item.Name, sql);
                        //    return sql;
                        //}

                        //Database.CreateSession().Execute(sql);
                        //return String.Empty;

                        // 非空字段作为可空字段新增,避开重建表
                        item.Nullable = true;
                    }

                    PerformSchema(sb, onlySql, DDLSchema.AddColumn, item);
                    if (!item.Description.IsNullOrEmpty())
                    {
                        PerformSchema(sb, onlySql, DDLSchema.AddColumnDescription, item);
                    }
                }
            }
            #endregion

            #region  除列
            var sbDelete = new StringBuilder();
            for (var i = dbtable.Columns.Count - 1; i >= 0; i--)
            {
                var item = dbtable.Columns[i];
                if (!etdic.ContainsKey(item.ColumnName.ToLower()))
                {
                    if (!String.IsNullOrEmpty(item.Description))
                    {
                        PerformSchema(sb, onlySql || noDelete, DDLSchema.DropColumnDescription, item);
                    }
                    PerformSchema(sbDelete, onlySql || noDelete, DDLSchema.DropColumn, item);
                }
            }
            if (sbDelete.Length > 0)
            {
                if (noDelete)
                {
                    // 不许删除列,显示日志
                    WriteLog("数据表中发现有多余字段,请手工执行以下语句删除:" + Environment.NewLine + sbDelete);
                }
                else
                {
                    if (sb.Length > 0)
                    {
                        sb.AppendLine(";");
                    }
                    sb.Append(sbDelete);
                }
            }
            #endregion

            #region 修改列
            // 开发时的实体数据库
            var entityDb = DbFactory.Create(entitytable.DbType);

            foreach (var item in entitytable.Columns)
            {
                if (!dbdic.TryGetValue(item.ColumnName, out var dbf))
                {
                    continue;
                }

                if (IsColumnTypeChanged(item, dbf))
                {
                    WriteLog("字段{0}.{1}类型需要由数据库的{2}改变为实体的{3}", entitytable.Name, item.Name, dbf.DataType, item.DataType);
                    PerformSchema(sb, noDelete, DDLSchema.AlterColumn, item, dbf);
                }
                if (IsColumnChanged(item, dbf, entityDb))
                {
                    PerformSchema(sb, noDelete, DDLSchema.AlterColumn, item, dbf);
                }

                //if (item.Description + "" != dbf.Description + "")
                if (FormatDescription(item.Description) != FormatDescription(dbf.Description))
                {
                    // 先删除旧注释
                    //if (dbf.Description != null) PerformSchema(sb, noDelete, DDLSchema.DropColumnDescription, dbf);

                    // 加上新注释
                    if (!item.Description.IsNullOrEmpty())
                    {
                        PerformSchema(sb, onlySql, DDLSchema.AddColumnDescription, item);
                    }
                }
            }
            #endregion

            return(sb.ToString());
        }
Example #2
0
        /// <summary>检查字段改变。某些数据库(如SQLite)没有添删改字段的DDL语法,可重载该方法,使用重建表方法ReBuildTable</summary>
        /// <param name="entitytable"></param>
        /// <param name="dbtable"></param>
        /// <param name="setting"></param>
        /// <returns></returns>
        protected virtual String CheckColumnsChange(IDataTable entitytable, IDataTable dbtable, NegativeSetting setting)
        {
            #region 准备工作
            var onlySql   = setting.CheckOnly;
            var sql       = String.Empty;
            var sb        = new StringBuilder();
            var entitydic = new Dictionary <String, IDataColumn>(StringComparer.OrdinalIgnoreCase);
            if (entitytable.Columns != null)
            {
                foreach (var item in entitytable.Columns)
                {
                    if (entitydic.ContainsKey(item.ColumnName.ToLower()))
                    {
                        WriteLog("《" + entitytable.Name + "》实体中存在重复列名,请检查《" + entitytable.TableName + "》表《" + item.Name + "》属性的ColumnName配置(目前配置为:" + item.ColumnName + ")。");
                        continue;
                    }
                    entitydic.Add(item.ColumnName.ToLower(), item);
                }
            }
            var dbdic = new Dictionary <String, IDataColumn>(StringComparer.OrdinalIgnoreCase);
            if (dbtable.Columns != null)
            {
                foreach (var item in dbtable.Columns)
                {
                    dbdic.Add(item.ColumnName.ToLower(), item);
                }
            }
            #endregion

            #region 新增列
            foreach (IDataColumn item in entitytable.Columns)
            {
                if (!dbdic.ContainsKey(item.ColumnName.ToLower()))
                {
                    //AddColumn(sb, item, onlySql);
                    PerformSchema(sb, onlySql, DDLSchema.AddColumn, item);
                    if (!String.IsNullOrEmpty(item.Description))
                    {
                        PerformSchema(sb, onlySql, DDLSchema.AddColumnDescription, item);
                    }

                    //! 以下已经不需要了,目前只有SQLite会采用重建表的方式添加删除字段。如果这里提前添加了字段,重建表的时候,会导致失败。

                    //// 这里必须给dbtable加加上当前列,否则下面如果刚好有删除列的话,会导致增加列成功,然后删除列重建表的时候没有新加的列
                    //dbtable.Columns.Add(item.Clone(dbtable));
                }
            }
            #endregion

            #region  除列
            var sbDelete = new StringBuilder();
            for (Int32 i = dbtable.Columns.Count - 1; i >= 0; i--)
            {
                var item = dbtable.Columns[i];
                if (!entitydic.ContainsKey(item.ColumnName.ToLower()))
                {
                    if (!String.IsNullOrEmpty(item.Description))
                    {
                        PerformSchema(sb, onlySql, DDLSchema.DropColumnDescription, item);
                    }
                    PerformSchema(sbDelete, setting.NoDelete, DDLSchema.DropColumn, item);
                }
            }
            if (sbDelete.Length > 0)
            {
                if (setting.NoDelete)
                {
                    //不许删除列,显示日志
                    WriteLog("数据表中发现有多余字段,请手工执行以下语句删除:" + Environment.NewLine + sbDelete.ToString());
                }
                else
                {
                    if (sb.Length > 0)
                    {
                        sb.AppendLine(";");
                    }
                    sb.Append(sbDelete.ToString());
                }
            }
            #endregion

            #region 修改列
            // 开发时的实体数据库
            var entityDb = DbFactory.Create(entitytable.DbType);

            foreach (var item in entitytable.Columns)
            {
                IDataColumn dbf = null;
                if (!dbdic.TryGetValue(item.ColumnName, out dbf))
                {
                    continue;
                }

                if (IsColumnTypeChanged(item, dbf))
                {
                    WriteLog("字段{0}.{1}类型需要由{2}改变为{3}", entitytable.Name, item.Name, dbf.DataType, item.DataType);
                    PerformSchema(sb, onlySql, DDLSchema.AlterColumn, item, dbf);
                }
                if (IsColumnChanged(item, dbf, entityDb))
                {
                    PerformSchema(sb, onlySql, DDLSchema.AlterColumn, item, dbf);
                }
                if (IsColumnDefaultChanged(item, dbf, entityDb))
                {
                    ChangeColmnDefault(sb, onlySql, item, dbf, entityDb);
                }

                if (item.Description + "" != dbf.Description + "")
                {
                    // 先删除旧注释
                    //if (!String.IsNullOrEmpty(dbf.Description)) DropColumnDescription(sb, dbf, onlySql);
                    //if (!String.IsNullOrEmpty(dbf.Description)) PerformSchema(sb, onlySql, DDLSchema.DropColumnDescription, dbf);
                    if (dbf.Description != null)
                    {
                        PerformSchema(sb, onlySql, DDLSchema.DropColumnDescription, dbf);
                    }

                    // 加上新注释
                    if (!String.IsNullOrEmpty(item.Description))
                    {
                        PerformSchema(sb, onlySql, DDLSchema.AddColumnDescription, item);
                    }
                }
            }
            #endregion

            return(sb.ToString());
        }