Esempio n. 1
0
        public override MemberExpression this[string name]
        {
            get
            {
                MemberExpression exp = null;
                if (Cache.TryGetValue(name, out exp))
                {
                    return(exp);
                }

                EntityModel       model = Runtime.RuntimeContext.Current.GetModelAsync <EntityModel>(ModelID).Result;
                EntityMemberModel m     = model.GetMember(name, false);
                if (m != null)
                {
                    switch (m.Type)
                    {
                    case EntityMemberType.DataField:
                        //case EntityMemberType.Formula:
                        //case EntityMemberType.Aggregate:
                        //case EntityMemberType.AutoNumber:
                        exp = new FieldExpression(name, this);
                        break;

                    case EntityMemberType.EntityRef:
                        var rm = (EntityRefModel)m;
                        if (!rm.IsAggregationRef)
                        {
                            exp = new EntityExpression(name, rm.RefModelIds[0], this);
                        }
                        else
                        {
                            throw new NotImplementedException("尚未实现聚合引用对象的表达式");
                        }
                        break;

                    case EntityMemberType.EntitySet:
                        var sm = (EntitySetModel)m;
                        //EntityRefModel erm = esm.RefModel[esm.RefMemberName] as EntityRefModel;
                        exp = new EntitySetExpression(name, this, sm.RefModelId);
                        break;

                    //case EntityMemberType.AggregationRefField:
                    //    exp = new AggregationRefFieldExpression(name, this);
                    //    break;
                    default:
                        throw new NotSupportedException($"EntityExpression.DefaultIndex[]: Not Supported MemberType [{m.Type.ToString()}].");
                    }
                    Cache.Add(name, exp);
                    return(exp);
                }
                //如果不包含判断是否继承,或EntityRef's DisplayText
                //if (name.EndsWith("DisplayText", StringComparison.Ordinal)) //TODO: 暂简单判断
                //{
                //    exp = new FieldExpression(name, this);
                //    Cache.Add(name, exp);
                //    return exp;
                //}
                throw new Exception($"Can not find member [{name}] in [{model.Name}].");
            }
        }
Esempio n. 2
0
        public async Task <object> Handle(DesignHub hub, InvokeArgs args)
        {
            // 获取接收到的参数
            string modelId          = args.GetString();
            string memberName       = args.GetString();
            int    entityMemberType = args.GetInt32();

            var node = hub.DesignTree.FindModelNode(ModelType.Entity, ulong.Parse(modelId));

            if (node == null)
            {
                throw new Exception("Can't find entity model node");
            }
            var model = (EntityModel)node.Model;

            if (!node.IsCheckoutByMe)
            {
                throw new Exception("Node has not checkout");
            }
            if (!CodeHelper.IsValidIdentifier(memberName))
            {
                throw new Exception("Name is invalid");
            }
            if (memberName == model.Name)
            {
                throw new Exception("Name can not same as Entity name");
            }
            if (model.Members.FindIndex(t => t.Name == memberName) >= 0) //if (model.ContainsMember(memberName))
            {
                throw new Exception("Name has exists");
            }
            EntityMemberModel res = entityMemberType switch
            {
                (int)EntityMemberType.DataField => NewDataField(model, memberName, ref args),
                (int)EntityMemberType.EntityRef => NewEntityRef(hub, model, memberName, ref args),
                (int)EntityMemberType.EntitySet => NewEntitySet(hub, model, memberName, ref args),
                _ => throw new NotImplementedException($"未实现的成员类型: {entityMemberType}"),
            };
Esempio n. 3
0
        /// <summary>
        /// 根据实体模型生成虚拟代码
        /// </summary>
        public static string GenEntityDummyCode(EntityModel model, string appName, DesignTree designTree)
        {
            var sb = StringBuilderCache.Acquire();

            //sb.Append("using System;\n");
            sb.Append($"namespace {appName}.Entities {{\n");

            //TODO:生成注释
            //sb.Append("/// <summary>\n");
            //sb.AppendFormat("/// {0}\n", model.Name);
            //sb.Append("/// </summary>\n");
            sb.Append($"public class {model.Name}");
            //根据映射存储不同生成不同的继承
            if (model.SysStoreOptions != null)
            {
                sb.Append($": {TypeHelper.Type_SysEntityBase}");
            }
            else if (model.SqlStoreOptions != null)
            {
                sb.Append($": {TypeHelper.Type_SqlEntityBase}");
            }
            else if (model.CqlStoreOptions != null)
            {
                sb.Append($": {TypeHelper.Type_CqlEntityBase}");
            }
            else
            {
                sb.Append($": {TypeHelper.Type_EntityBase}");
            }
            sb.Append(" {\n");

            //生成静态TypeId属性
            sb.AppendFormat("[{0}(\"TypeId\")]\n", TypeHelper.MemberAccessInterceptorAttribute);
            sb.AppendLine("public const ulong TypeId = 0;");

            //生成成员属性
            EntityMemberModel[] ls = model.Members.ToArray();
            for (int i = 0; i < ls.Length; i++)
            {
                EntityMemberModel mm = ls[i];
                if (!string.IsNullOrEmpty(mm.Comment))
                {
                    sb.Append("/// <summary>\n");
                    sb.AppendFormat("/// {0}\n", mm.Comment);
                    sb.Append("/// </summary>\n");
                }

                string typeString = "object";
                bool   readOnly   = false;
                GetEntityMemberTypeStringAndReadOnly(mm, ref typeString, ref readOnly, designTree);

                sb.Append($"public {typeString} {mm.Name} {{get;");
                if (!readOnly)
                {
                    sb.Append("set;");
                }
                sb.Append("}\n");
            }

            //如果是分区表,生成带分区参数的构造方法
            if (model.SysStoreOptions != null && model.SysStoreOptions.HasPartitionKeys)
            {
                sb.Append($"public {model.Name}(");
                bool hasPreArg = false;
                for (int i = 0; i < model.SysStoreOptions.PartitionKeys.Length; i++)
                {
                    if (model.SysStoreOptions.PartitionKeys[i].MemberId != 0) //排除特殊分区键
                    {
                        if (hasPreArg)
                        {
                            sb.Append(',');
                        }
                        var    member     = model.GetMember(model.SysStoreOptions.PartitionKeys[i].MemberId, true);
                        string typeString = "object";
                        bool   readOnly   = false;
                        GetEntityMemberTypeStringAndReadOnly(member, ref typeString, ref readOnly, designTree);
                        sb.Append($"{typeString} {member.Name}");
                        hasPreArg = true;
                    }
                }
                sb.Append("){}");
            }
            //如果是SqlStore且具备主键生成主键参数构造,同时生成静态LoadAsync方法 //TODO:考虑排除自增主键
            if (model.SqlStoreOptions != null && model.SqlStoreOptions.HasPrimaryKeys)
            {
                var ctorsb = StringBuilderCache.Acquire();
                ctorsb.Append($"public {model.Name}(");
                sb.AppendFormat("[{0}(\"{1}\")]\n",
                                TypeHelper.InvocationInterceptorAttribute, LoadEntityInterceptor.Name);
                sb.Append($"public static System.Threading.Tasks.Task<{model.Name}> LoadAsync(");
                for (int i = 0; i < model.SqlStoreOptions.PrimaryKeys.Count; i++)
                {
                    var    mm         = model.GetMember(model.SqlStoreOptions.PrimaryKeys[i].MemberId, true);
                    string typeString = "object";
                    bool   readOnly   = false;
                    GetEntityMemberTypeStringAndReadOnly(mm, ref typeString, ref readOnly, designTree);
                    if (i != 0)
                    {
                        sb.Append(","); ctorsb.Append(",");
                    }
                    sb.Append($"{typeString} {mm.Name}"); //TODO:mm.Name转为小驼峰
                    ctorsb.Append($"{typeString} {mm.Name}");
                }
                sb.Append(") {return null;}\n");
                ctorsb.Append("){}");
                sb.Append(StringBuilderCache.GetStringAndRelease(ctorsb));
            }
            //如果是CqlStore生成主键参数构造, 同时生成静态LoadAsync方法
            if (model.CqlStoreOptions != null)
            {
                var ctorsb = StringBuilderCache.Acquire();
                ctorsb.Append($"public {model.Name}(");
                //sb.AppendFormat("[{0}(\"LoadEntity\")]\n", TypeHelper.InvocationInterceptorAttribute);
                //sb.Append($"public static System.Threading.Tasks.Task<{model.Name}> LoadAsync(");
                var pks = model.CqlStoreOptions.PrimaryKey.GetAllPKs();
                for (int i = 0; i < pks.Length; i++)
                {
                    var    mm         = model.GetMember(pks[i], true);
                    string typeString = "object";
                    bool   readOnly   = false;
                    GetEntityMemberTypeStringAndReadOnly(mm, ref typeString, ref readOnly, designTree);
                    if (i != 0)
                    {
                        ctorsb.Append(",");
                    }
                    //sb.Append($"{typeString} {mm.Name}"); //TODO:mm.Name转为小驼峰
                    ctorsb.Append($"{typeString} {mm.Name}");
                }
                //sb.Append(") {return null;}\n");
                ctorsb.Append("){}");
                sb.Append(StringBuilderCache.GetStringAndRelease(ctorsb));
            }

            //系统存储生成索引接口
            if (model.SysStoreOptions != null && model.SysStoreOptions.HasIndexes)
            {
                foreach (var index in model.SysStoreOptions.Indexes)
                {
                    sb.Append("public interface ");
                    sb.Append(index.Name);
                    sb.Append(" :IEntityIndex<");
                    sb.Append(model.Name);
                    sb.Append("> {");
                    for (int i = 0; i < index.Fields.Length; i++)
                    {
                        sb.Append("/// <summary>\n");
                        sb.AppendFormat("/// [{0}] {1}\n", i, index.Name); //TODO:OrderBy注释
                        sb.Append("/// </summary>\n");
                        var    mm         = model.GetMember(index.Fields[i].MemberId, true);
                        string typeString = "object";
                        bool   readOnly   = false;
                        GetEntityMemberTypeStringAndReadOnly(mm, ref typeString, ref readOnly, designTree);
                        sb.AppendFormat("{0} {1} {{get;}}", typeString, mm.Name);
                    }
                    sb.Append("}");
                }
            }

            //生成FetchEntitySet方法
            //sb.AppendFormat("\t\t[{0}(\"FetchEntitySetMethod\")]{1}", TypeHelper.InvocationInterceptorAttribute, Environment.NewLine);
            //sb.AppendFormat("\t\tpublic void FetchEntitySet<T>(System.Func<{0}.Entities.{1},EntityList<T>> selector) where T: EntityBase {{}}{2}"
            //                , model.AppID, model.Name, Environment.NewLine);
            //sb.AppendFormat("\t\t[{0}(\"FetchEntitySetMethod\")]{1}", TypeHelper.InvocationInterceptorAttribute, Environment.NewLine);
            //sb.AppendFormat("\t\tpublic void FetchEntitySet<T>(System.Func<{0}.Entities.{1},EntityList<T>> selector, System.Func<T, EntityBase[]> includes) where T: EntityBase {{}}{2}"
            //, model.AppID, model.Name, Environment.NewLine);

            sb.Append("}\n}");
            return(StringBuilderCache.GetStringAndRelease(sb));
        }
Esempio n. 4
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. 5
0
        private static void BuildFieldDefinition(StringBuilder sb, EntityMemberModel member)
        {
            switch (member.Type)
            {
            case EntityMemberType.DataField:
                //case EntityMemberType.FieldSet: //TODO:fix FieldSet
            {
                var fieldName = member.Name;
                //var dataType = member.Type == EntityMemberType.DataField ?
                //    ((DataFieldModel)member).DataType : ((FieldSetModel)member).DataType;
                var dataType = ((DataFieldModel)member).DataType;
                sb.Append($"\"{fieldName}\" ");
                //if (member.Type == EntityMemberType.FieldSet)
                //    sb.Append(" set<");
                switch (dataType)
                {
                case EntityFieldType.String:
                    sb.Append("text"); break;

                case EntityFieldType.Byte:
                    sb.Append("tinyint"); break;

                case EntityFieldType.Int16:
                    sb.Append("smallint"); break;

                case EntityFieldType.Enum:
                case EntityFieldType.Int32:
                    sb.Append("int"); break;

                case EntityFieldType.Int64:
                    sb.Append("bigint"); break;

                case EntityFieldType.DateTime:
                    sb.Append("timestamp"); break;

                case EntityFieldType.Guid:
                    sb.Append("uuid"); break;

                case EntityFieldType.Boolean:
                    sb.Append("boolean"); break;

                case EntityFieldType.Float:
                    sb.Append("float"); break;

                case EntityFieldType.Double:
                    sb.Append("double"); break;

                case EntityFieldType.Binary:
                    sb.Append("blob"); break;

                default:
                    throw new NotImplementedException();
                }
                //if (member.Type == EntityMemberType.FieldSet)
                //    sb.Append(">");
            }
            break;

            default:
                throw new NotSupportedException();
            }
        }