C# - 在DataSet中使用具有相同名称和命名空间的多个DataTable

时间:2012-01-25 16:18:04

标签: .net xml sql-server-2008

假设我有一个MS SQL Server数据库表名为" GROUPS"如下:

GROUP_ID    GROUP_NAME    DESCRIPTION
    1        Grp1            Null
    2        Grp2            Null
    3        Grp3            Test

GROUP_ID是自动增量主要字段,GROUP_NAME是唯一的非null varchar字段,Description是允许空值(可选)的varchar字段。

我正在尝试将一些XML输出作为Web服务生成,以供表信息的其他进程使用。 必须以特定方式输出XML。

最终目标如下:

<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
    <GROUP>
        <GROUP_ID>1</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
        <DESCRIPTION/>
    </GROUP>
    <GROUP>
        <GROUP_ID>2</GROUP_ID>
        <GROUP_NAME>Grp2</GROUP_NAME>
        <DESCRIPTION/>
    </GROUP>
    <GROUP>
        <GROUP_ID>3</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
        <DESCRIPTION>Test</DESCRIPTION>
    </GROUP>
</GROUPS>

这个程序几乎达到了预期的目标:

    string sql = "SELECT * FROM GROUPS";
    Response.ContentType = "application/xml"; // Set the page to output XML
        SqlDataAdapter da = new SqlDataAdapter(sql, conn); // SQL Adapter, conn is an already open SQL connection
        DataSet ds = new DataSet("GROUPS"); // Root Node of XML doc will be "GROUPS"
        da.Fill(ds, "GROUP"); // Each record node is a "GROUP"
        XmlTextWriter xml = new XmlTextWriter(Response.Output) { Formatting = Formatting.None }; // XML writer
        xml.WriteStartDocument(); // XML header
        ds.WriteXml(xml); // Write XML output

此过程的问题在于它不提供所需的空节点,例如表中的空值。它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
    <GROUP>
        <GROUP_ID>1</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
    </GROUP>
    <GROUP>
        <GROUP_ID>2</GROUP_ID>
        <GROUP_NAME>Grp2</GROUP_NAME>
    </GROUP>
    <GROUP>
        <GROUP_ID>3</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
        <DESCRIPTION>Test</DESCRIPTION>
    </GROUP>
</GROUPS>

在进行一些研究之后,尝试使用以下步骤创建所需的输出:

        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandText = "SELECT * FROM GROUPS";
        SqlDataReader row = cmd.ExecuteReader();

        DataSet ds = new DataSet("GROUPS");

        while (row.Read())
        {

            DataTable table1 = new DataTable("GROUP" + row["GROUP_ID"]); // This line is the issue
            object[] columns = new object[row.FieldCount];


            for (int i = 0; i < row.FieldCount; i++)
            {

                string name = row.GetName(i);

                    table1.Columns.Add(name);
                    columns[i] = DBstr(row[i]);

            }

            table1.Rows.Add(columns);
            ds.Tables.Add(table1);

        }

        row.Close();

        Response.ContentType = "application/xml"; // Set the page to output XML
        XmlTextWriter xml = new XmlTextWriter(Response.Output) { Formatting = Formatting.None }; // XML writer
        xml.WriteStartDocument(); // XML header
        ds.WriteXml(xml, XmlWriteMode.IgnoreSchema); // Write XML output


    public static string DBstr(Object obj)
    {
        if (obj == null || obj == DBNull.Value)
        {
            return String.Empty; // Default value for null DB value
        }

        else if (obj.GetType() == typeof(DateTime))
        {
            return ((DateTime)obj).ToString("MM/dd/yyyy");
        }
        else
        {
            return obj.ToString();
        }
    }

这里的问题是我必须为每个DataTable或唯一的命名空间指定一个唯一的名称。在从DataSet写出xml之前。 所以它看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<GROUPS>
    <GROUP1>
        <GROUP_ID>1</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
        <DESCRIPTION/>
    </GROUP1>
    <GROUP2>
        <GROUP_ID>2</GROUP_ID>
        <GROUP_NAME>Grp2</GROUP_NAME>
        <DESCRIPTION/>
    </GROUP2>
    <GROUP3>
        <GROUP_ID>3</GROUP_ID>
        <GROUP_NAME>Grp1</GROUP_NAME>
        <DESCRIPTION>Test</DESCRIPTION>
    </GROUP3>
</GROUPS>

或者,每个GROUP行都会抛出一个xmlns标记。

无论哪种方式,都是不受欢迎的。那么在这里使用C#获得所需目标的最简单方法是什么?

2 个答案:

答案 0 :(得分:1)

尝试更改查询

  

string sql =“SELECT * FROM GROUPS”;

到下面

string sql = "SELECT GROUP_ID, GROUP_NAME, IsNull(DESCRIPTION, '') as DESCRIPTION  FROM GROUPS";

答案 1 :(得分:0)

如果没有自定义序列化程序,我认为您无法达到您想要的效果。 DataTable名称在设计上是唯一的,并且DataSet的序列化尊重该唯一性,因为它们必须是可反序列化的,这意味着序列化后名称必须是唯一的。