Esempio n. 1
0
        private static string GetDataFieldType(DataFieldModel df)
        {
            switch (df.DataType)
            {
            case EntityFieldType.EntityId:
            case EntityFieldType.Guid:
            case EntityFieldType.Binary:
            case EntityFieldType.String:
                return("string");

            case EntityFieldType.Boolean:
                return("boolean");

            case EntityFieldType.Byte:
            case EntityFieldType.Decimal:
            case EntityFieldType.Double:
            case EntityFieldType.Enum:
            case EntityFieldType.Float:
            case EntityFieldType.UInt16:
            case EntityFieldType.Int16:
            case EntityFieldType.UInt32:
            case EntityFieldType.Int32:
            case EntityFieldType.UInt64:
            case EntityFieldType.Int64:
                return("number");

            case EntityFieldType.DateTime:
                return("Date");

            default:
                return("any");
            }
        }
Esempio n. 2
0
        static TestController()
        {
            app = new ApplicationModel("appbox", Consts.SYS);

            emploee = new EntityModel(Consts.SYS_EMPLOEE_MODEL_ID, Consts.EMPLOEE, EntityStoreType.StoreWithMvcc);
            var name = new DataFieldModel(emploee, Consts.NAME, EntityFieldType.String);

            emploee.AddSysMember(name, Consts.EMPLOEE_NAME_ID);
            var account = new DataFieldModel(emploee, Consts.ACCOUNT, EntityFieldType.String);

            account.AllowNull = true;
            emploee.AddSysMember(account, Consts.EMPLOEE_ACCOUNT_ID);
            var password = new DataFieldModel(emploee, Consts.PASSWORD, EntityFieldType.Binary);

            password.AllowNull = true;
            emploee.AddSysMember(password, Consts.EMPLOEE_PASSWORD_ID);
        }
Esempio n. 3
0
        internal static string BuildInsertEntityCommand(Entity entity, bool checkExists = false)
        {
            //TODO: use Prepared statements and cache it, 另可考虑JSON方式

            var model = entity.Model;
            var sb    = StringBuilderCache.Acquire();

            sb.Append($"INSERT INTO \"{model.Name}\" (");
            var vsb = StringBuilderCache.Acquire();

            vsb.Append(") VALUES (");

            for (int i = 0; i < entity.Members.Length; i++)
            {
                ref EntityMember m = ref entity.Members[i];
                if (m.HasValue || m.HasChanged)
                {
                    if (i != 0)
                    {
                        sb.Append(',');
                        vsb.Append(',');
                    }

                    switch (m.MemberType)
                    {
                    case EntityMemberType.DataField:
                    {
                        DataFieldModel fm = (DataFieldModel)model.GetMember(m.Id, true);
                        sb.Append($"\"{fm.Name}\"");
                        BuildDataFieldValue(vsb, ref m);
                    }
                    break;

                    //case EntityMemberType.FieldSet:
                    //    {
                    //        FieldSetModel fm = (FieldSetModel)model.GetMember(m.Id, true);
                    //        sb.Append($"\"{fm.Name}\"");
                    //        BuildFieldSetValue(vsb, ref m);
                    //    }
                    //    break;
                    default:
                        throw new NotSupportedException("Not supported member type");
                    }
                }
            }
Esempio n. 4
0
        private EntityModel MakeTestSqlModel()
        {
            var model  = new EntityModel(0x12345678ul, "Emploee", new SqlStoreOptions(0x1234ul));
            var m_code = new DataFieldModel(model, "Code", EntityFieldType.Int32);

            model.AddSysMember(m_code, 1);
            var m_name = new DataFieldModel(model, "Name", EntityFieldType.String);

            model.AddSysMember(m_name, 2);

            var pk = new List <FieldWithOrder>
            {
                new FieldWithOrder {
                    MemberId = 1, OrderByDesc = false
                }
            };

            model.SqlStoreOptions.SetPrimaryKeys(model, pk);
            return(model);
        }
Esempio n. 5
0
        private static void GetEntityMemberTypeStringAndReadOnly(EntityMemberModel mm,
                                                                 ref string typeString, ref bool readOnly, DesignTree designTree)
        {
            switch (mm.Type)
            {
            case EntityMemberType.DataField:
                //判断是否是枚举
                DataFieldModel dmm = mm as DataFieldModel;
                //if (dmm.DataType == EntityFieldType.Enum)
                //{
                //    if (string.IsNullOrEmpty(dmm.EnumModelID))
                //        typeString = "int";
                //    else
                //    {
                //        string[] sr = dmm.EnumModelID.Split('.');
                //        typeString = sr[0] + ".Enums." + sr[1];
                //    }
                //}
                if (dmm.DataType == EntityFieldType.EntityId)
                {
                    typeString = "EntityId";
                }
                else
                {
                    typeString = dmm.DataType.GetValueType().FullName;     //TODO:简化类型名称
                }

                //系统存储分区键与sql存储的主键为只读
                readOnly |= dmm.IsPartitionKey || dmm.IsPrimaryKey;

                if (dmm.AllowNull && (dmm.DataType != EntityFieldType.String &&
                                      dmm.DataType != EntityFieldType.EntityId &&
                                      dmm.DataType != EntityFieldType.Binary && typeString != "object"))
                {
                    typeString += "?";
                }
                break;

            case EntityMemberType.EntityRef:
                EntityRefModel rm = (EntityRefModel)mm;
                if (rm.IsAggregationRef)
                {
                    typeString = TypeHelper.Type_EntityBase;
                }
                else
                {
                    if (rm.RefModelIds.Count == 0)     //Todo:待移除,因误删除模型引用项导致异常
                    {
                        typeString = TypeHelper.Type_EntityBase;
                    }
                    else
                    {
                        var targetModelNode = designTree.FindModelNode(ModelType.Entity, rm.RefModelIds[0]);
                        typeString = $"{targetModelNode.AppNode.Model.Name}.Entities.{targetModelNode.Model.Name}";
                    }
                }
                break;

            case EntityMemberType.EntitySet:
            {
                EntitySetModel sm = (EntitySetModel)mm;
                var            targetModelNode = designTree.FindModelNode(ModelType.Entity, sm.RefModelId);
                typeString = $"EntityList<{targetModelNode.AppNode.Model.Name}.Entities.{targetModelNode.Model.Name}>";
                readOnly   = true;
            }
            break;

            case EntityMemberType.AggregationRefField:
                typeString = "object";
                readOnly   = true;
                break;

            //case EntityMemberType.Formula:
            //case EntityMemberType.Aggregate:
            //FormulaModel fmm = mm as FormulaModel;
            //typeString = TypeService.GetEntityFieldValueType(fmm.DataType).FullName;
            //readOnly = true;
            //break;
            case EntityMemberType.Tracker:
                throw ExceptionHelper.NotImplemented();

            //GetEntityMemberTypeStringAndReadOnly(
            //    (mm as TrackerModel).TargetMember, ref typeString, ref readOnly);
            //readOnly = true;
            //break;
            case EntityMemberType.AutoNumber:
                typeString = "string";
                readOnly   = true;
                break;

            //case EntityMemberType.ImageRef:
            //typeString = TypeHelper.Type_IImageSource;
            //readOnly = false;
            //break;
            default:
                typeString = "object";
                break;
            }
        }
Esempio n. 6
0
        static TestHelper()
        {
            SysAppModel = new ApplicationModel("appbox", Consts.SYS, Consts.SYS_APP_ID);

            AdminPermissionModel     = new PermissionModel(Consts.SYS_PERMISSION_ADMIN_ID, "Admin");
            DeveloperPermissionModel = new PermissionModel(Consts.SYS_PERMISSION_DEVELOPER_ID, "Developer");

            OrderStatusModel = new EnumModel(SYS_ENUM_MODEL_ID | (1 << IdUtil.MODELID_SEQ_OFFSET), "OrderStatus");
            OrderStatusModel.Items.Add(new EnumModelItem("New", 0));
            OrderStatusModel.Items.Add(new EnumModelItem("Paid", 1));

            EmploeeModel = new EntityModel(Consts.SYS_EMPLOEE_MODEL_ID, Consts.EMPLOEE, EntityStoreType.StoreWithMvcc);
            var name = new DataFieldModel(EmploeeModel, Consts.NAME, EntityFieldType.String);

            EmploeeModel.AddSysMember(name, Consts.EMPLOEE_NAME_ID);
            var account = new DataFieldModel(EmploeeModel, Consts.ACCOUNT, EntityFieldType.String);

            account.AllowNull = true;
            EmploeeModel.AddSysMember(account, Consts.EMPLOEE_ACCOUNT_ID);
            var password = new DataFieldModel(EmploeeModel, Consts.PASSWORD, EntityFieldType.Binary);

            password.AllowNull = true;
            EmploeeModel.AddSysMember(password, Consts.EMPLOEE_PASSWORD_ID);

            //Add indexes
            var ui_account_pass = new EntityIndexModel(EmploeeModel, "UI_Account_Password", true,
                                                       new FieldWithOrder[] { new FieldWithOrder(Consts.EMPLOEE_ACCOUNT_ID) },
                                                       new ushort[] { Consts.EMPLOEE_PASSWORD_ID });

            EmploeeModel.SysStoreOptions.AddSysIndex(EmploeeModel, ui_account_pass, Consts.EMPLOEE_UI_ACCOUNT_ID);

            //测试用分区表
            VehicleStateModel = new EntityModel(((ulong)Consts.SYS_APP_ID << 32) | 18, "VehicleState", EntityStoreType.StoreWithMvcc);
            var vid = new DataFieldModel(VehicleStateModel, "VehicleId", EntityFieldType.Int32);

            VehicleStateModel.AddMember(vid);
            var lng = new DataFieldModel(VehicleStateModel, "Lng", EntityFieldType.Float);

            VehicleStateModel.AddMember(lng);
            var lat = new DataFieldModel(VehicleStateModel, "Lat", EntityFieldType.Float);

            VehicleStateModel.AddMember(lat);
            var pks = new PartitionKey[1];

            pks[0] = new PartitionKey()
            {
                MemberId = vid.MemberId, OrderByDesc = false
            };
            VehicleStateModel.SysStoreOptions.SetPartitionKeys(VehicleStateModel, pks);

            //测试树状结构
            ulong orgUnitModelId = ((ulong)Consts.SYS_APP_ID << 32) | 19;

            OrgUnitModel = new EntityModel(orgUnitModelId, "OrgUnit", EntityStoreType.StoreWithMvcc);
            var ouName = new DataFieldModel(OrgUnitModel, "Name", EntityFieldType.String);

            OrgUnitModel.AddSysMember(ouName, 1 << IdUtil.MEMBERID_SEQ_OFFSET);
            var parentId = new DataFieldModel(OrgUnitModel, "ParentId", EntityFieldType.EntityId, true);

            parentId.AllowNull = true;
            OrgUnitModel.AddSysMember(parentId, 2 << IdUtil.MEMBERID_SEQ_OFFSET);
            var parent = new EntityRefModel(OrgUnitModel, "Parent", orgUnitModelId, new ushort[] { parentId.MemberId });

            parent.AllowNull = true;
            OrgUnitModel.AddSysMember(parent, 3 << IdUtil.MEMBERID_SEQ_OFFSET);
            var childs = new EntitySetModel(OrgUnitModel, "Childs", orgUnitModelId, parent.MemberId);

            OrgUnitModel.AddSysMember(childs, 4 << IdUtil.MEMBERID_SEQ_OFFSET);

            //----以下测试映射至SqlStore的实体---
            SqlStoreModel = new DataStoreModel(DataStoreKind.Sql, "appbox.Store.PostgreSQL;appbox.Store.PgSqlStore", "DemoDB");

            ulong cityModelId = ((ulong)Consts.SYS_APP_ID << 32) | 25;

            CityModel = new EntityModel(cityModelId, "City", new SqlStoreOptions(SqlStoreModel.Id));
            var cityCode = new DataFieldModel(CityModel, "Code", EntityFieldType.Int32);

            CityModel.AddMember(cityCode);
            var cityName = new DataFieldModel(CityModel, "Name", EntityFieldType.String);

            CityModel.AddMember(cityName);
            var cityPerson = new DataFieldModel(CityModel, "Persons", EntityFieldType.Int32);

            CityModel.AddMember(cityPerson);
            var cityPk = new List <FieldWithOrder>();

            cityPk.Add(new FieldWithOrder {
                MemberId = cityCode.MemberId, OrderByDesc = false
            });
            CityModel.SqlStoreOptions.SetPrimaryKeys(CityModel, cityPk);

            ulong customerModelId = ((ulong)Consts.SYS_APP_ID << 32) | 26;

            CustomerModel = new EntityModel(customerModelId, "Customer", new SqlStoreOptions(SqlStoreModel.Id));
            var customerId = new DataFieldModel(CustomerModel, "Id", EntityFieldType.Int32);

            CustomerModel.AddMember(customerId);
            var customerName = new DataFieldModel(CustomerModel, "Name", EntityFieldType.String);

            CustomerModel.AddMember(customerName);
            var customerCityId = new DataFieldModel(CustomerModel, "CityId", EntityFieldType.Int32, true);

            CustomerModel.AddMember(customerCityId);
            var customerCity = new EntityRefModel(CustomerModel, "City", cityModelId, new ushort[] { customerCityId.MemberId });

            CustomerModel.AddMember(customerCity);
            var customerPk = new List <FieldWithOrder>();

            customerPk.Add(new FieldWithOrder {
                MemberId = customerId.MemberId, OrderByDesc = false
            });
            CustomerModel.SqlStoreOptions.SetPrimaryKeys(CustomerModel, customerPk);

            ulong orderModelId = ((ulong)Consts.SYS_APP_ID << 32) | 27;

            OrderModel = new EntityModel(orderModelId, "Order", new SqlStoreOptions(SqlStoreModel.Id));
            var orderId = new DataFieldModel(OrderModel, "Id", EntityFieldType.Int32);

            OrderModel.AddMember(orderId);
            var orderCustomerId = new DataFieldModel(OrderModel, "CustomerId", EntityFieldType.Int32, true);

            OrderModel.AddMember(orderCustomerId);
            var orderCustomer = new EntityRefModel(OrderModel, "Customer", customerModelId, new ushort[] { orderCustomerId.MemberId });

            OrderModel.AddMember(orderCustomer);
            var orderPk = new List <FieldWithOrder>();

            orderPk.Add(new FieldWithOrder {
                MemberId = orderId.MemberId, OrderByDesc = false
            });
            OrderModel.SqlStoreOptions.SetPrimaryKeys(OrderModel, orderPk);
        }
Esempio n. 7
0
        public void GetDataField(Action <DataFieldModel, Exception> callback)
        {
            var item = new DataFieldModel("Machine state [design]");

            callback?.Invoke(item, null);
        }
Esempio n. 8
0
        /// <summary>
        /// 返回树状结构的实体集合
        /// </summary>
        /// <param name="childrenMember">例:q.T["SubItems"]</param>
        /// <returns></returns>
        public async Task <EntityList> ToTreeListAsync(MemberExpression childrenMember)
        {
            //TODO:目前实现仅支持单一主键且为Guid的树状结构
            Debug.Assert(ReferenceEquals(childrenMember.Owner, T));
            var         children = (EntitySetExpression)childrenMember;
            EntityModel model    = await RuntimeContext.Current.GetModelAsync <EntityModel>(T.ModelID);

            EntitySetModel childrenModel = (EntitySetModel)model.GetMember(children.Name, true);
            EntityRefModel parentModel   = (EntityRefModel)model.GetMember(childrenModel.RefMemberId, true);
            DataFieldModel parentIdModel = (DataFieldModel)model.GetMember(parentModel.FKMemberIds[0], true);

            TreeParentIDMember = (FieldExpression)T[parentIdModel.Name];
            var pk = model.SqlStoreOptions.PrimaryKeys[0].MemberId;

            AddAllSelects(this, model, T, null);

            //TODO:加入自动排序
            //if (!string.IsNullOrEmpty(setmodel.RefRowNumberMemberName))
            //{
            //    SqlSortItem sort = new SqlSortItem(T[setmodel.RefRowNumberMemberName], SortType.ASC);
            //    SortItems.Insert(0, sort);
            //}

            //如果没有设置任何条件,则设置默认条件为查询根级开始
            if (Equals(null, Filter))
            {
                Filter = TreeParentIDMember == null;
            }

            Purpose = QueryPurpose.ToEntityTreeList;
            EntityList list = new EntityList(childrenModel);
            var        db   = SqlStore.Get(model.SqlStoreOptions.StoreModelId);
            var        dic  = new Dictionary <Guid, Entity>(); //TODO: fix pk

            using var cmd  = db.BuildQuery(this);
            using var conn = db.MakeConnection();
            await conn.OpenAsync();

            cmd.Connection = conn;
            Log.Debug(cmd.CommandText);

            using var reader = await cmd.ExecuteReaderAsync();

            while (await reader.ReadAsync())
            {
                Entity obj = FillEntity(model, reader);
                //设置obj本身的EntitySet成员为已加载,防止从数据库中再次加载
                obj.InitEntitySetForLoad(childrenModel);

                var parentId = obj.GetGuidNullable(parentIdModel.MemberId);
                if (parentId.HasValue && dic.TryGetValue(parentId.Value, out Entity parent))
                {
                    parent.GetEntitySet(childrenModel.MemberId).Add(obj);
                }
                else
                {
                    list.Add(obj);
                }

                dic.Add(obj.GetGuid(pk), obj);
            }
            return(list);
        }
Esempio n. 9
0
        public Entity FetchToEntity(EntityModel model)
        {
            var members = model.Members;
            var entity  = new Entity(model);

            for (int i = 0; i < members.Count; i++)
            {
                switch (members[i].Type)
                {
                case EntityMemberType.DataField:
                {
                    DataFieldModel dfm = (DataFieldModel)members[i];
                    if (!rawRow.IsNull(dfm.Name))
                    {
                        switch (dfm.DataType)
                        {
                        case EntityFieldType.String:
                            entity.SetString(dfm.MemberId, rawRow.GetValue <string>(dfm.Name)); break;

                        case EntityFieldType.DateTime:
                            entity.SetDateTime(dfm.MemberId,
                                               rawRow.GetValue <DateTimeOffset>(dfm.Name).LocalDateTime); break;

                        case EntityFieldType.Int16:
                            entity.SetInt16(dfm.MemberId, rawRow.GetValue <short>(dfm.Name)); break;

                        case EntityFieldType.Enum:
                        case EntityFieldType.Int32:
                            entity.SetInt32(dfm.MemberId, rawRow.GetValue <int>(dfm.Name)); break;

                        //case EntityFieldType.Decimal:
                        //    entity.SetDecimal(dfm.MemberId, rawRow.GetValue<Decimal>(dfm.Name)); break;
                        case EntityFieldType.Boolean:
                            entity.SetBoolean(dfm.MemberId, rawRow.GetValue <bool>(dfm.Name)); break;

                        case EntityFieldType.Guid:
                            entity.SetGuid(dfm.MemberId, rawRow.GetValue <Guid>(dfm.Name)); break;

                        case EntityFieldType.Byte:
                            entity.SetByte(dfm.MemberId, unchecked ((byte)rawRow.GetValue <sbyte>(dfm.Name))); break;

                        case EntityFieldType.Binary:
                            entity.SetBytes(dfm.MemberId, rawRow.GetValue <byte[]>(dfm.Name)); break;

                        case EntityFieldType.Float:
                            entity.SetFloat(dfm.MemberId, rawRow.GetValue <float>(dfm.Name)); break;

                        case EntityFieldType.Double:
                            entity.SetDouble(dfm.MemberId, rawRow.GetValue <double>(dfm.Name)); break;

                        default: throw new NotSupportedException("Row.FetchToEntity.DataField");
                        }
                    }
                }
                break;

                //case EntityMemberType.FieldSet:
                //    {
                //        FieldSetModel fsm = (FieldSetModel)members[i];
                //        if (!rawRow.IsNull(fsm.FieldName))
                //        {
                //            switch (fsm.DataType)
                //            {
                //                case EntityFieldType.String:
                //                    entity.SetFieldSetValue<string>(fsm.Name, new FieldSet<string>(rawRow.GetValue<IEnumerable<string>>(fsm.FieldName))); break;
                //                case EntityFieldType.DateTime:
                //                    entity.SetFieldSetValue<DateTime>(fsm.Name,
                //                        new FieldSet<DateTime>(rawRow.GetValue<IEnumerable<DateTimeOffset>>(fsm.FieldName).Select(t => t.DateTime))); break;
                //                case EntityFieldType.Enum:
                //                case EntityFieldType.Integer:
                //                    entity.SetFieldSetValue<int>(fsm.Name, new FieldSet<int>(rawRow.GetValue<IEnumerable<int>>(fsm.FieldName))); break;
                //                case EntityFieldType.Decimal:
                //                    entity.SetFieldSetValue<Decimal>(fsm.Name, new FieldSet<Decimal>(rawRow.GetValue<IEnumerable<Decimal>>(fsm.FieldName))); break;
                //                case EntityFieldType.Guid:
                //                    entity.SetFieldSetValue<Guid>(fsm.Name, new FieldSet<Guid>(rawRow.GetValue<IEnumerable<Guid>>(fsm.FieldName))); break;
                //                case EntityFieldType.Byte:
                //                    entity.SetFieldSetValue<byte>(fsm.Name, new FieldSet<byte>(rawRow.GetValue<IEnumerable<byte>>(fsm.FieldName))); break;
                //                case EntityFieldType.Float:
                //                    entity.SetFieldSetValue<float>(fsm.Name, new FieldSet<float>(rawRow.GetValue<IEnumerable<float>>(fsm.FieldName))); break;
                //                case EntityFieldType.Double:
                //                    entity.SetFieldSetValue<double>(fsm.Name, new FieldSet<double>(rawRow.GetValue<IEnumerable<double>>(fsm.FieldName))); break;
                //                default: throw new NotSupportedException("Row.FetchToEntity.FieldSet");
                //            }
                //        }
                //    }
                //    break;
                default: throw new NotSupportedException("Row.FetchToEntity");
                }
            }
            entity.AcceptChanges(); //todo: check need this?
            return(entity);
        }
Esempio n. 10
0
        protected override IList <DbCommand> MakeAlterTable(EntityModel model, Design.IDesignContext ctx)
        {
            //TODO:***处理主键变更

            var tableName = model.GetSqlTableName(false, ctx);

            StringBuilder    sb;
            bool             needCommand = false;               //用于判断是否需要处理NpgsqlCommand
            List <string>    fks         = new List <string>(); //引用外键列表
            List <DbCommand> commands    = new List <DbCommand>();

            //List<DbCommand> funcCmds = new List<DbCommand>();
            //先处理表名称有没有变更,后续全部使用新名称
            if (model.IsNameChanged)
            {
                var oldTableName   = model.GetSqlTableName(true, ctx);
                var renameTableCmd = new NpgsqlCommand($"ALTER TABLE \"{oldTableName}\" RENAME TO \"{tableName}\"");
                commands.Add(renameTableCmd);
            }

            //处理删除的成员
            var deletedMembers = model.Members.Where(t => t.PersistentState == PersistentState.Deleted).ToArray();

            if (deletedMembers != null && deletedMembers.Length > 0)
            {
                #region ----删除的成员----
                sb = StringBuilderCache.Acquire();
                foreach (var m in deletedMembers)
                {
                    if (m.Type == EntityMemberType.DataField)
                    {
                        needCommand = true;
                        sb.AppendFormat("ALTER TABLE \"{0}\" DROP COLUMN \"{1}\";", tableName, ((DataFieldModel)m).SqlColOriginalName);
                    }
                    else if (m.Type == EntityMemberType.EntityRef)
                    {
                        EntityRefModel rm = (EntityRefModel)m;
                        if (!rm.IsAggregationRef)
                        {
                            var fkName = $"FK_{rm.Owner.Id}_{rm.MemberId}"; //TODO:特殊处理DbFirst导入表的外键约束名称
                            fks.Add($"ALTER TABLE \"{tableName}\" DROP CONSTRAINT \"{fkName}\";");
                        }
                    }
                }

                var cmdText = StringBuilderCache.GetStringAndRelease(sb);
                if (needCommand)
                {
                    //加入删除的外键SQL
                    for (int i = 0; i < fks.Count; i++)
                    {
                        sb.Insert(0, fks[i]);
                        sb.AppendLine();
                    }

                    commands.Add(new NpgsqlCommand(cmdText));
                }
                #endregion
            }

            //reset
            needCommand = false;
            fks.Clear();

            //处理新增的成员
            var addedMembers = model.Members.Where(t => t.PersistentState == PersistentState.Detached).ToArray();
            if (addedMembers != null && addedMembers.Length > 0)
            {
                #region ----新增的成员----
                sb = StringBuilderCache.Acquire();
                foreach (var m in addedMembers)
                {
                    if (m.Type == EntityMemberType.DataField)
                    {
                        needCommand = true;
                        sb.AppendFormat("ALTER TABLE \"{0}\" ADD COLUMN ", tableName);
                        BuildFieldDefine((DataFieldModel)m, sb, false);
                        sb.Append(";");
                    }
                    else if (m.Type == EntityMemberType.EntityRef)
                    {
                        var rm = (EntityRefModel)m;
                        if (!rm.IsAggregationRef) //只有非聚合引合创建外键
                        {
                            fks.Add(BuildForeignKey(rm, ctx, tableName));
                            //考虑CreateGetTreeNodeChildsDbFuncCommand
                        }
                    }
                }

                var cmdText = StringBuilderCache.GetStringAndRelease(sb);
                if (needCommand)
                {
                    //加入关系
                    sb.AppendLine();
                    for (int i = 0; i < fks.Count; i++)
                    {
                        sb.AppendLine(fks[i]);
                    }

                    commands.Add(new NpgsqlCommand(cmdText));
                }
                #endregion
            }

            //reset
            needCommand = false;
            fks.Clear();

            //处理修改的成员
            var changedMembers = model.Members.Where(t => t.PersistentState == PersistentState.Modified).ToArray();
            if (changedMembers != null && changedMembers.Length > 0)
            {
                #region ----修改的成员----
                foreach (var m in changedMembers)
                {
                    if (m.Type == EntityMemberType.DataField)
                    {
                        DataFieldModel dfm = (DataFieldModel)m;
                        //先处理数据类型变更,变更类型或者变更AllowNull或者变更默认值
                        if (dfm.IsDataTypeChanged)
                        {
                            sb = StringBuilderCache.Acquire();
                            sb.AppendFormat("ALTER TABLE \"{0}\" ALTER COLUMN ", tableName);
                            string defaultValue = BuildFieldDefine(dfm, sb, true);

                            if (dfm.AllowNull)
                            {
                                sb.AppendFormat(",ALTER COLUMN \"{0}\" DROP NOT NULL", dfm.SqlColOriginalName);
                            }
                            else
                            {
                                if (dfm.DataType == EntityFieldType.Binary)
                                {
                                    throw new Exception("Binary field must be allow null");
                                }
                                sb.AppendFormat(",ALTER COLUMN \"{0}\" SET NOT NULL,ALTER COLUMN \"{0}\" SET DEFAULT {1}",
                                                dfm.SqlColOriginalName, defaultValue);
                            }

                            commands.Add(new NpgsqlCommand(StringBuilderCache.GetStringAndRelease(sb)));
                        }

                        //再处理重命名列
                        if (m.IsNameChanged)
                        {
                            var renameColCmd = new NpgsqlCommand($"ALTER TABLE \"{tableName}\" RENAME COLUMN \"{dfm.SqlColOriginalName}\" TO \"{dfm.SqlColName}\"");
                            commands.Add(renameColCmd);
                        }
                    }

                    //TODO:处理EntityRef更新与删除规则
                    //注意不再需要同旧实现一样变更EntityRef的外键约束名称 "ALTER TABLE \"XXX\" RENAME CONSTRAINT \"XXX\" TO \"XXX\""
                    //因为ModelFirst的外键名称为FK_{MemberId};CodeFirst为导入的名称
                }
                #endregion
            }

            //处理索引变更
            BuildIndexes(model, commands, tableName);

            return(commands);
        }