【问题标题】:Linq to XML to Generate DDLsLinq to XML 生成 DDL
【发布时间】:2010-10-26 12:50:09
【问题描述】:

我们以本问题末尾的格式将数据库定义存储为 XML。我遇到的问题是获取模式列表、这些模式中的表、这些表中的列(所有这些都带有相关信息)。我当前的代码(包含在示例 XML 下方)抓取所有内容,完全忽略嵌套,并且由于多个模式,多次返回每个表/列。

示例 XML:

<schemas>
    <schema>
        <name>schema_name1</name>
        <tables>
            <table>
                <name>table_name2</name>
                <comment>comment string2</comment>
                <type>innodb2</type>
                <columns>
                    <column>
                        <name>column_name3</name>
                        <type>data_type3</type>
                        <size>3</size>
                        <nullable>not null3</nullable>
                        <comment>comment string3</comment>
                    </column>
                    <column>
                        <name>column_name4</name>
                        <type>data_type4</type>
                        <size>4</size>
                        <nullable>not null4</nullable>
                        <comment>comment string4</comment>
                    </column>
                </columns>
            </table>
        </tables>
    </schema>
    <schema>
        <name>schema_name5</name>
        <tables>
            <table>
                <name>table_name6</name>
                <comment>comment string6</comment>
                <type>innodb6</type>
                <columns>
                    <column>
                        <name>column_name7</name>
                        <type>data_type7</type>
                        <size>7</size>
                        <nullable>not null7</nullable>
                        <comment>comment string7</comment>
                    </column>
                </columns>
            </table>
        </tables>
    </schema>
</schemas>

C# 代码:

    XDocument xml_input = XDocument.Load(FILE_IN);
    string column_create = "";
    //build a list of all schemas in xml
    var schemas = from s in xml_input.Descendants("schema")
                  select new
                  {
                      name = s.Element("name").Value
                  };
    //loop through all schemas
    foreach (var s in schemas)
    {
        //write the schema creation lines
        Console.WriteLine("DROP SCHEMA IF EXISTS " + s.name + ";");
        Console.WriteLine("CREATE SCHEMA " + s.name + ";");
        //build a list of all tables in schema
        var tables = from t in xml_input.Descendants("schema")
                                        .Descendants("table")
                     select new
                     {
                         name = t.Element("name").Value,
                         comment = t.Element("comment").Value,
                         type = t.Element("type").Value
                     };
        //loop through all tables in schema
        foreach (var t in tables)
        {
            //write the beginning of the table creation lines
            Console.WriteLine("CREATE TABLE " + s.name + "." + t.name + " (");
            //build a list of all columns in the schema
            var columns = from c in xml_input.Descendants("schema")
                                             .Descendants("table")
                                             .Descendants("column")
                          select new
                          {
                              name = c.Element("name").Value,
                              type = c.Element("type").Value,
                              size = c.Element("size").Value,
                              comment = c.Element("comment").Value
                          };
            //loop through all columns in table
            foreach (var c in columns)
            {
                //build the column creation line
                column_create = c.name + " " + c.type;
                if (c.size != null)
                {
                    column_create += "(" + c.size + ")";
                }
                if (c.comment != null)
                {
                    column_create += " COMMENT '" + c.comment + "'";
                }
                column_create += ", ";
                //write the column creation line
                Console.WriteLine(column_create);
            }
            //write the end of the table creation lines
            Console.WriteLine(")");
            if (t.comment != null)
            {
                Console.WriteLine("COMMENT '" + t.comment + "'");
            }
            if (t.type != null)
            {
                Console.WriteLine("TYPE = " + t.type);
            }
            Console.WriteLine(";");
        }
    }

关于如何保留嵌套结构的任何想法?我也无法处理可选的 XML 元素(例如表格注释或大小字段,它们不适用于所有数据类型)。

谢谢!

【问题讨论】:

    标签: c# xml linq linq-to-xml ddl


    【解决方案1】:

    以下是如何保留嵌套结构。将 XElement 添加到您的匿名类型以用作嵌套查询的源。

        XDocument xml_input = XDocument.Load(FILE_IN);
            string column_create = "";
            //build a list of all schemas in xml
            var schemas = from s in xml_input.Descendants("schema")
                          select new
                          {
                              schema = s,
                              name = s.Element("name").Value
                          };
            //loop through all schemas
            foreach (var s in schemas)
            {
                //write the schema creation lines
                Console.WriteLine("DROP SCHEMA IF EXISTS " + s.name + ";");
                Console.WriteLine("CREATE SCHEMA " + s.name + ";");
                //build a list of all tables in schema
                var tables = from t in s.schema.Descendants("table")
                             select new
                             {
                                 table = t,
                                 name = t.Element("name").Value,
                                 comment = t.Element("comment").Value,
                                 type = t.Element("type").Value
                             };
                //loop through all tables in schema
                foreach (var t in tables)
                {
                    //write the beginning of the table creation lines
                    Console.WriteLine("CREATE TABLE " + s.name + "." + t.name + " (");
                    //build a list of all columns in the schema
                    var columns = from c in t.table.Descendants("column")
                                  select new
                                  {
                                      name = c.Element("name").Value,
                                      type = c.Element("type").Value,
                                      size = c.Element("size").Value,
                                      comment = c.Element("comment").Value
                                  };
                    //loop through all columns in table
                    foreach (var c in columns)
                    {
                        //build the column creation line
                        column_create = c.name + " " + c.type;
                        if (c.size != null)
                        {
                            column_create += "(" + c.size + ")";
                        }
                        if (c.comment != null)
                        {
                            column_create += " COMMENT '" + c.comment + "'";
                        }
                        column_create += ", ";
                        //write the column creation line
                        Console.WriteLine(column_create);
                    }
                    //write the end of the table creation lines
                    Console.WriteLine(")");
                    if (t.comment != null)
                    {
                        Console.WriteLine("COMMENT '" + t.comment + "'");
                    }
                    if (t.type != null)
                    {
                        Console.WriteLine("TYPE = " + t.type);
                    }
                    Console.WriteLine(";");
                }
            }
    

    处理可选元素的一种方法是让您的 xml 在本列注释中没有值时包含空元素:

          <column>
            <name>column_name4</name>
            <type>data_type4</type>
            <size>4</size>
            <nullable>not null4</nullable>
            <comment/>
          </column>
    

    这将在您的查询中返回一个空字符串,因此将代码更改为:

    if (!string.IsNullOrEmpty(c.comment))
        {
            column_create += " COMMENT '" + c.comment + "'";
        }
    

    【讨论】:

    • 太棒了!像魅力一样工作!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多