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"); } }
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); }
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"); } } }
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); }
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; } }
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); }
public void GetDataField(Action <DataFieldModel, Exception> callback) { var item = new DataFieldModel("Machine state [design]"); callback?.Invoke(item, null); }
/// <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); }
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); }
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); }