Exemple #1
0
        /// <summary>
        /// 字段名是否重复
        /// </summary>
        /// <returns></returns>
        internal bool FieldNameDuplicated(out string duplicatedString)
        {
            m_Set.Clear();

            duplicatedString = null;

            foreach (var h in header)
            {
                if (TableHelper.IgnoreHeader(h))
                {
                    continue;
                }

                if (m_Set.Contains(h.fieldName))
                {
                    duplicatedString = h.fieldName;
                    return(true);
                }
                m_Set.Add(h.fieldName);
            }

            return(false);
        }
Exemple #2
0
        static async Task Load(string[] args)
        {
            int processorCount = System.Environment.ProcessorCount;

            ThreadPool.SetMinThreads(Math.Max(4, processorCount), 5);
            ThreadPool.SetMaxThreads(Math.Max(16, processorCount * 4), 10);

            string        clientOutDir = null, serverOutDir = null, csOutDir = null, excelDir = null;
            CmdlineHelper cmder = new CmdlineHelper(args);

            if (cmder.Has("--out_client"))
            {
                clientOutDir = cmder.Get("--out_client");
            }
            else
            {
                Console.WriteLine("out_client missing"); return;
            }
            ////if (cmder.Has("--out_server")) { serverOutDir = cmder.Get("--out_server"); } else { return; }
            if (cmder.Has("--in_excel"))
            {
                excelDir = cmder.Get("--in_excel");
            }
            else
            {
                Console.WriteLine("in_excel missing"); return;
            }

            //Console.WriteLine(clientOutDir);
            //Console.WriteLine(excelDir);

            //创建导出目录
            if (!Directory.Exists(clientOutDir))
            {
                Directory.CreateDirectory(clientOutDir);
            }
            //if (!Directory.Exists(serverOutDir)) Directory.CreateDirectory(serverOutDir);

            bool gen_client_cs = false;

            if (cmder.Has("--out_cs"))
            {
                csOutDir = cmder.Get("--out_cs");
                if (!Directory.Exists(csOutDir))
                {
                    Directory.CreateDirectory(csOutDir);
                }

                gen_client_cs = true;
            }

            string[] files = Directory.GetFiles(excelDir, "*.xlsx", SearchOption.TopDirectoryOnly);
            var      tasks = new List <Task>(files.Length * 4);
            var      time  = new Stopwatch();

            time.Start();
            foreach (string filepath in files)
            {
                var fileName = Path.GetFileName(filepath);
                if (fileName.StartsWith("~"))
                {
                    continue;
                }

                //Console.WriteLine($"[program] load excel {filepath}");

                var excelDatas = TableHelper.LoadExcel(filepath);

                tasks.Add(Task.Run(() =>
                {
                    foreach (var excelData in excelDatas)
                    {
                        string clientPath = clientOutDir + excelData.tablName + ".txt";
                        //string serverPath = serverOutDir + sheets[i].SheetName + ".txt";

                        TableHelper.WriteByteAsset(excelData, clientPath);

                        if (gen_client_cs)
                        {
                            var codepath = csOutDir + "/t" + excelData.tablName + ".cs";
                            CodeGen.MakeCsharpFile(excelData, codepath);
                        }
                    }
                }));
            }

            await Task.WhenAll(tasks);

            Console.WriteLine();
            Console.WriteLine("export success!");

            time.Stop();
            Console.WriteLine($"process finish: {time.ElapsedMilliseconds} ms");
        }
Exemple #3
0
 /// <summary>
 /// key的个数
 /// </summary>
 /// <returns></returns>
 internal int GetKeyCount() => header.Count(h => TableHelper.IsKey(h));
Exemple #4
0
        internal static void MakeCsharpFile(ExcelData excelData, string codepath)
        {
            //const string k_CsFileName = "CsvData.cs";
            //string csfile = codepath + k_CsFileName;

            var csfile = codepath;

            var sb = new StringBuilder(2048);

            var unit           = new CodeCompileUnit();
            var tableNamespace = new CodeNamespace("Saro.Table");

            unit.Namespaces.Add(tableNamespace);
            tableNamespace.Imports.Add(new CodeNamespaceImport("System.Collections"));
            tableNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
            tableNamespace.Imports.Add(new CodeNamespaceImport("System.IO"));
            tableNamespace.Imports.Add(new CodeNamespaceImport("System.Text"));

            var enumDefineList = new List <int>();

            #region item class

            var itemClass = new CodeTypeDeclaration(excelData.GetEntityClassName());
            itemClass.TypeAttributes = System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Sealed;
            tableNamespace.Types.Add(itemClass);

            int index = -1;
            enumDefineList.Clear();
            foreach (var header in excelData.header)
            {
                index++;
                if (header.define == TableHelper.HeaderFilter.k_ENUM_KEY)
                {
                    enumDefineList.Add(index);
                }
                if (TableHelper.IgnoreHeader(header))
                {
                    continue;
                }

                if (!TableHelper.s_TypeLut.TryGetValue(header.fieldTypeName, out Type t))
                {
                    throw new Exception("type is not support: " + header.fieldTypeName);
                }
                var memberFiled = new CodeMemberField(t, header.fieldName);
                memberFiled.Attributes = MemberAttributes.Public;

                memberFiled.Comments.Add(new CodeCommentStatement("<summary>", true));
                memberFiled.Comments.Add(new CodeCommentStatement(header.fieldComment, true));
                memberFiled.Comments.Add(new CodeCommentStatement("</summary>", true));
                itemClass.Members.Add(memberFiled);
            }

            #endregion

            #region table class

            var tableClass = new CodeTypeDeclaration(excelData.GetWrapperClassName());
            tableClass.TypeAttributes = System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Sealed;
            tableClass.BaseTypes.Add(new CodeTypeReference("BaseTable", new CodeTypeReference[] { new CodeTypeReference(excelData.GetEntityClassName()), new CodeTypeReference(excelData.GetWrapperClassName()) }));
            tableNamespace.Types.Add(tableClass);

            #region load method
            {
                var loadMethod = new CodeMemberMethod();
                tableClass.Members.Add(loadMethod);
                loadMethod.Name       = "Load";
                loadMethod.ReturnType = new CodeTypeReference(typeof(bool));
                loadMethod.Attributes = MemberAttributes.Override | MemberAttributes.Public;

                sb.AppendLine("\t\t\tif (m_Loaded) return true;");
                sb.AppendLine($"\t\t\tvar bytes = GetBytes(\"{excelData.tablName}.txt\");");
                sb.AppendLine();
                sb.AppendLine("\t\t\tusing (var ms = new MemoryStream(bytes, false))");
                sb.AppendLine("\t\t\t{");
                sb.AppendLine("\t\t\t\tusing (var br = new BinaryReader(ms))");
                sb.AppendLine("\t\t\t\t{");
                sb.AppendLine("\t\t\t\t\tvar version = br.ReadInt32();//version");
                sb.AppendLine("\t\t\t\t\tif (version != TableLoader.k_DataVersion)\n\t\t\t\t\t\tthrow new System.Exception($\"table error version. file:{version}  exe:{TableLoader.k_DataVersion}\");\n");
                sb.AppendLine("\t\t\t\t\tvar dataLen = br.ReadInt32();");
                sb.AppendLine("\t\t\t\t\tfor (int i = 0; i < dataLen; i++)");
                sb.AppendLine("\t\t\t\t\t{");
                sb.AppendLine($"\t\t\t\t\t\tvar data = new {excelData.GetEntityClassName()}();");
                bool first = true;
                foreach (var header in excelData.header)
                {
                    if (TableHelper.IgnoreHeader(header))
                    {
                        continue;
                    }

                    if (!TableHelper.s_TypeLut.TryGetValue(header.fieldTypeName, out Type t))
                    {
                        throw new Exception("type is not support: " + header.fieldTypeName);
                    }
                    if (t == typeof(byte))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadByte();");
                    }
                    else if (t == typeof(int))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadInt32();");
                    }
                    else if (t == typeof(long))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadInt64();");
                    }
                    else if (t == typeof(float))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadSingle();");
                    }
                    else if (t == typeof(bool))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadBoolean();");
                    }
                    else if (t == typeof(string))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadString();");
                    }
                    else if (t == typeof(byte[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new byte[len];");
                        sb.AppendLine($"\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadByte();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(int[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new int[len];");
                        sb.AppendLine($"\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadInt32();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(long[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new long[len];");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadInt64();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(float[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new float[len];");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadSingle();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(Dictionary <int, int>))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new Dictionary<int, int>(len);");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tvar key = br.ReadInt32();");
                        sb.AppendLine($"\t\t\t\t\t\t\tvar val = br.ReadInt32();");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}.Add(key, val);");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                }
                sb.AppendLine("\t\t\t\t\t\tvar _key = br.ReadUInt64();");
                sb.AppendLine("\t\t\t\t\t\tm_Datas[_key] = data;");
                sb.AppendLine("\t\t\t\t\t}");
                sb.AppendLine("\t\t\t\t}");
                sb.AppendLine("\t\t\t}");
                sb.AppendLine("\t\t\tm_Loaded = true;");
                loadMethod.Statements.Add(new CodeSnippetStatement(sb.ToString()));
                loadMethod.Statements.Add(new CodeMethodReturnStatement(
                                              new CodeSnippetExpression("true")));

                sb.Clear();
            }
            #endregion

            #region loadasync method
            {
                var loadAsyncMethod = new CodeMemberMethod();
                tableClass.Members.Add(loadAsyncMethod);
                loadAsyncMethod.Name       = "LoadAsync";
                loadAsyncMethod.ReturnType = new CodeTypeReference("async System.Threading.Tasks.ValueTask<bool>");
                loadAsyncMethod.Attributes = MemberAttributes.Override | MemberAttributes.Public;

                sb.AppendLine("\t\t\tif (m_Loaded) return true;");
                sb.AppendLine($"\t\t\tvar bytes = await GetBytesAsync(\"{excelData.tablName}.txt\");");
                sb.AppendLine();
                sb.AppendLine("\t\t\tusing (var ms = new MemoryStream(bytes, false))");
                sb.AppendLine("\t\t\t{");
                sb.AppendLine("\t\t\t\tusing (var br = new BinaryReader(ms))");
                sb.AppendLine("\t\t\t\t{");
                sb.AppendLine("\t\t\t\t\tvar version = br.ReadInt32();//version");
                sb.AppendLine("\t\t\t\t\tif (version != TableLoader.k_DataVersion)\n\t\t\t\t\t\tthrow new System.Exception($\"table error version. file:{version}  exe:{TableLoader.k_DataVersion}\");\n");
                sb.AppendLine("\t\t\t\t\tvar dataLen = br.ReadInt32();");
                sb.AppendLine("\t\t\t\t\tfor (int i = 0; i < dataLen; i++)");
                sb.AppendLine("\t\t\t\t\t{");
                sb.AppendLine($"\t\t\t\t\t\tvar data = new {excelData.GetEntityClassName()}();");
                bool first = true;
                foreach (var header in excelData.header)
                {
                    if (TableHelper.IgnoreHeader(header))
                    {
                        continue;
                    }

                    if (!TableHelper.s_TypeLut.TryGetValue(header.fieldTypeName, out Type t))
                    {
                        throw new Exception("type is not support: " + header.fieldTypeName);
                    }
                    if (t == typeof(byte))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadByte();");
                    }
                    else if (t == typeof(int))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadInt32();");
                    }
                    else if (t == typeof(long))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadInt64();");
                    }
                    else if (t == typeof(float))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadSingle();");
                    }
                    else if (t == typeof(bool))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadBoolean();");
                    }
                    else if (t == typeof(string))
                    {
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = br.ReadString();");
                    }
                    else if (t == typeof(byte[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new byte[len];");
                        sb.AppendLine($"\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadByte();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(int[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new int[len];");
                        sb.AppendLine($"\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadInt32();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(long[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new long[len];");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadInt64();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(float[]))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new float[len];");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}[j] = br.ReadSingle();");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                    else if (t == typeof(Dictionary <int, int>))
                    {
                        if (first)
                        {
                            sb.AppendLine($"\t\t\t\t\t\tvar len = br.ReadByte();");
                            first = false;
                        }
                        else
                        {
                            sb.AppendLine($"\t\t\t\t\t\tlen = br.ReadByte();");
                        }
                        sb.AppendLine($"\t\t\t\t\t\tdata.{header.fieldName} = new Dictionary<int, int>(len);");
                        sb.AppendLine("\t\t\t\t\t\tfor (int j = 0; j < len; j++)");
                        sb.AppendLine("\t\t\t\t\t\t{");
                        sb.AppendLine($"\t\t\t\t\t\t\tvar key = br.ReadInt32();");
                        sb.AppendLine($"\t\t\t\t\t\t\tvar val = br.ReadInt32();");
                        sb.AppendLine($"\t\t\t\t\t\t\tdata.{header.fieldName}.Add(key, val);");
                        sb.AppendLine("\t\t\t\t\t\t}");
                    }
                }
                sb.AppendLine("\t\t\t\t\t\tvar _key = br.ReadUInt64();");
                sb.AppendLine("\t\t\t\t\t\tm_Datas[_key] = data;");
                sb.AppendLine("\t\t\t\t\t}");
                sb.AppendLine("\t\t\t\t}");
                sb.AppendLine("\t\t\t}");
                sb.AppendLine("\t\t\tm_Loaded = true;");
                loadAsyncMethod.Statements.Add(new CodeSnippetStatement(sb.ToString()));
                loadAsyncMethod.Statements.Add(new CodeMethodReturnStatement(
                                                   new CodeSnippetExpression("true")));

                sb.Clear();
            }
            #endregion

            #region query method
            {
                var keyCount        = excelData.GetKeyCount();
                var keyNames        = excelData.GetKeyNames();
                var combinedKeyName = "__combinedkey";
                if (keyCount == 1)
                {
                    sb.AppendLine($"\t\tpublic static {excelData.GetEntityClassName()} Query(int {keyNames[0]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]});");
                }
                else if (keyCount == 2)
                {
                    sb.AppendLine($"\t\tpublic static {excelData.GetEntityClassName()} Query(int {keyNames[0]}, int {keyNames[1]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]});");
                }
                else if (keyCount == 3)
                {
                    sb.AppendLine($"\t\tpublic static {excelData.GetEntityClassName()} Query(int {keyNames[0]}, int {keyNames[1]}, int {keyNames[2]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]}, {keyNames[2]});");
                }
                else if (keyCount == 4)
                {
                    sb.AppendLine($"\t\tpublic static {excelData.GetEntityClassName()} Query(int {keyNames[0]}, int {keyNames[1]}, int {keyNames[2]}, int {keyNames[3]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]}, {keyNames[2]}, {keyNames[3]});");
                }

                sb.AppendLine($"\t\t\tif (!Get().Load()) throw new System.Exception(\"load table failed.type: \" + nameof({excelData.GetEntityClassName()}));");
                sb.AppendLine($"\t\t\tif (Get().m_Datas.TryGetValue({combinedKeyName}, out {excelData.GetEntityClassName()} t))");
                sb.AppendLine("\t\t\t{");
                sb.AppendLine("\t\t\t\treturn t;");
                sb.AppendLine("\t\t\t}");
                sb.AppendLine($"\t\t\tthrow new System.Exception(\"null table. type: \" + nameof({excelData.GetEntityClassName()}));");
                sb.AppendLine("\t\t}");

                var queryMethod = new CodeSnippetTypeMember(sb.ToString());

                tableClass.Members.Add(queryMethod);

                sb.Clear();
            }
            #endregion


            #region queryasync method
            {
                var keyCount        = excelData.GetKeyCount();
                var keyNames        = excelData.GetKeyNames();
                var combinedKeyName = "__combinedkey";
                if (keyCount == 1)
                {
                    sb.AppendLine($"\t\tpublic static async System.Threading.Tasks.ValueTask<{excelData.GetEntityClassName()}> QueryAsync(int {keyNames[0]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]});");
                }
                else if (keyCount == 2)
                {
                    sb.AppendLine($"\t\tpublic static async System.Threading.Tasks.ValueTask<{excelData.GetEntityClassName()}> QueryAsync(int {keyNames[0]}, int {keyNames[1]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]});");
                }
                else if (keyCount == 3)
                {
                    sb.AppendLine($"\t\tpublic static async System.Threading.Tasks.ValueTask<{excelData.GetEntityClassName()}> QueryAsync(int {keyNames[0]}, int {keyNames[1]}, int {keyNames[2]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]}, {keyNames[2]});");
                }
                else if (keyCount == 4)
                {
                    sb.AppendLine($"\t\tpublic static async System.Threading.Tasks.ValueTask<{excelData.GetEntityClassName()}> QueryAsync(int {keyNames[0]}, int {keyNames[1]}, int {keyNames[2]}, int {keyNames[3]})");
                    sb.AppendLine("\t\t{");
                    sb.AppendLine($"\t\t\tvar {combinedKeyName} = KeyHelper.GetKey({keyNames[0]}, {keyNames[1]}, {keyNames[2]}, {keyNames[3]});");
                }

                sb.AppendLine($"\t\t\tvar result = await Get().LoadAsync();");
                sb.AppendLine($"\t\t\tif (!result) throw new System.Exception(\"load table failed.type: \" + nameof({excelData.GetEntityClassName()}));");
                sb.AppendLine($"\t\t\tif (Get().m_Datas.TryGetValue({combinedKeyName}, out {excelData.GetEntityClassName()} t))");
                sb.AppendLine("\t\t\t{");
                sb.AppendLine("\t\t\t\treturn t;");
                sb.AppendLine("\t\t\t}");
                sb.AppendLine($"\t\t\tthrow new System.Exception(\"null table. type: \" + nameof({excelData.GetEntityClassName()}));");
                sb.AppendLine("\t\t}");

                var queryMethod = new CodeSnippetTypeMember(sb.ToString());

                tableClass.Members.Add(queryMethod);

                sb.Clear();
            }
            #endregion


            #region PrintTable method

            var printTableMethod = new CodeMemberMethod();
            tableClass.Members.Add(printTableMethod);
            printTableMethod.Name       = "PrintTable";
            printTableMethod.ReturnType = new CodeTypeReference(typeof(string));
            printTableMethod.Attributes = MemberAttributes.Final | MemberAttributes.Public;

            sb.AppendLine("\t\t\tStringBuilder sb = null;");

            sb.AppendLine("#if ENABLE_TABLE_LOG");

            sb.AppendLine("\t\t\tsb = new StringBuilder(2048);");

            sb.AppendLine("\t\t\tforeach (var data in m_Datas.Values)");
            sb.AppendLine("\t\t\t{");
            foreach (var header in excelData.header)
            {
                if (TableHelper.IgnoreHeader(header))
                {
                    continue;
                }

                if (!TableHelper.s_TypeLut.TryGetValue(header.fieldTypeName, out Type t))
                {
                    throw new Exception("type is not support: " + header.fieldTypeName);
                }

                if (t.IsValueType ||
                    t == typeof(string))
                {
                    sb.AppendLine($"\t\t\t\tsb.Append(data.{header.fieldName}).Append(\"\\t\");");
                }
                else if (t == typeof(byte[]) ||
                         t == typeof(int[]) ||
                         t == typeof(long[]) ||
                         t == typeof(float[]))
                {
                    sb.AppendLine($"\t\t\t\tsb.Append(string.Join(\",\", data.{header.fieldName})).Append(\"\\t\");");
                }
                else if (t == typeof(Dictionary <int, int>))
                {
                    sb.AppendLine($"\t\t\t\tsb.Append(string.Join(\",\", data.{header.fieldName})).Append(\"\\t\");");
                }
            }
            sb.AppendLine("\t\t\t\tsb.AppendLine();");
            sb.AppendLine("\t\t\t}");

            sb.AppendLine("#endif");

            printTableMethod.Statements.Add(new CodeSnippetStatement(sb.ToString()));
            printTableMethod.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression("sb?.ToString()")));

            sb.Clear();

            #endregion

            #endregion

            #region enum define

            if (enumDefineList.Count > 0)
            {
                var enumType = new CodeTypeDeclaration(excelData.GetEnumName());
                enumType.IsEnum = true;
                tableNamespace.Types.Add(enumType);
                for (int j = 0; j < excelData.rowValues.Count; j++)
                {
                    for (int k = 0; k < enumDefineList.Count; k++)
                    {
                        sb.Append(excelData.rowValues[j][enumDefineList[k]]);
                        if (k != enumDefineList.Count - 1)
                        {
                            sb.Append("_");
                        }
                    }
                    enumType.Members.Add(new CodeMemberField()
                    {
                        Name = sb.ToString(), InitExpression = new CodePrimitiveExpression(int.Parse(excelData.rowValues[j][0]))
                    });
                    sb.Clear();
                }
            }

            #endregion

            var options = new FileStreamOptions {
                Mode = FileMode.Create, Access = FileAccess.Write, Share = FileShare.ReadWrite
            };

            var tw = new IndentedTextWriter(new StreamWriter(csfile, options), "\t");
            {
                var provider = new CSharpCodeProvider();
                tw.WriteLine("//------------------------------------------------------------------------------");
                tw.WriteLine("// File   : {0}", Path.GetFileName(codepath));
                tw.WriteLine("// Author : Saro");
                tw.WriteLine("// Time   : {0}", DateTime.Now.ToString());
                tw.WriteLine("//------------------------------------------------------------------------------");
                provider.GenerateCodeFromCompileUnit(unit, tw, new CodeGeneratorOptions()
                {
                    BracingStyle = "C"
                });
                tw.Close();
            }
        }