65.9K
CodeProject 正在变化。 阅读更多。
Home

将 Microsoft ADOMD 数据源转换为 JSON 的方法

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.88/5 (11投票s)

2015 年 2 月 25 日

CPOL

5分钟阅读

viewsIcon

23631

将 Microsoft ADOMD 数据源转换为 JSON 的方法

引言

大家好,希望你们都还好。本文将帮助您了解如何将 ADOMD 数据源转换为 JavaScript Object Notation (JSON) 格式。如果您不熟悉 ADOMD,请在此处阅读阅读

正如我所说,我们将把源转换为 JSON,所以您必须了解什么是 JSON 及其重要性。我说得对吗?

JSON 的重要性

JSON 代表 JavaScript Object Notation(基本上 JSON 本身就是 JavaScript)。它是一种我们可以使用 JavaScript 格式化和分析的数据格式。它易于使用。您可以在此处获取更多信息获取更多信息

背景

在过去的几个月里,我一直在处理 ADOMD 数据源。当您对 SQL 变得精通时,可能会遇到一些处理源的困难。就我的经验而言,在 ADOMD 中处理数据不像在 SQL 中那么容易。ADOMD 数据源可能是 Excel 文件。在我的案例中,客户所做的就是将他们创建的 Excel 文件上传到数据库。

回到正题,当您的 ADOMD 应用程序中有一个只接受 JSON 格式数据的客户端网格时,您该怎么办?我搜索了许多天将源转换为 JSON 的解决方案。但我找不到解决方案。所以我想到将 ADOMD 数据源(单元集)转换为 HTML 表,然后在客户端将其转换为 JSON。您可以在此处阅读该文章阅读

那是在初步阶段,当时我对 ADOMD 还很陌生。我们开发人员从不停止谷歌搜索,对吧?坦率地说,我热衷于研发工作(这可能需要我们搜索得越来越多)。现在我发现了一些将源转换为 JSON 的方法。我想分享这些信息,以便有人认为它很有用。

我在 MVC 中工作,并使用以下命名空间进行处理。

using Newtonsoft.Json;

流程

在这里,我没有像这类应用程序中常用的那样将 ADOMD 数据源作为单元集。这里我将解释两种方法或途径来完成这个过程。

  1. 使用 ADOMD 数据适配器
  2. 使用 ADOMD 数据读取器

在第一部分中,我们将使用一个适配器,并将数据填充到数据表中,然后在服务器端将其转换为 JSON。此方法的问题在于,它需要大量的循环来进行格式化和创建。

在第二部分中,我们将使用数据读取器,当对象读取时,我们将进行格式化和创建 JSON,这只需要一个循环。听起来很棒,对吧?

使用代码

让我们来解释第一种方法。

1. 使用 ADOMD 数据适配器

当您使用适配器并将数据填充到数据表中时,您遇到的问题是,数据表列名会不同,并且会包含多维数据集单元格的层次结构。

例如:数据表头包含“。[MEMBER_CAPTION]

所以在这里,我只是从所有头列中确定实际的头名称。我使用循环来实现这一点。

请注意,这完全基于我的需求。您可能需要执行不同的格式化过程。

为了进行格式化,我使用了以下函数。

public DataTable HiMapColumnExcuteQuery(string query, string adoMDConnection)
{
    string readerString = string.Empty;
    try {
        using(AdomdConnection conn = new AdomdConnection(adoMDConnection)) {
            conn.Open();
            using(AdomdCommand cmd = new AdomdCommand(query, conn)) {
                DataTable dt = new DataTable();
                AdomdDataAdapter da = new AdomdDataAdapter(cmd);
                da.Fill(dt);
                List < string > curColumn = new List < string > ();
                string col = string.Empty;
                if (dt.Rows.Count > 0 && dt.Columns.Count > 0)
                {
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        string columnName = dt.Columns[i].ColumnName.Replace(".[MEMBER_CAPTION]",
                            "").Trim();
                        curColumn = columnName.Split(new string[] {
                            "."
                        },
                        StringSplitOptions.None).ToList();
                        col = curColumn[curColumn.Count - 1].Replace("[", "").Replace("]", "");
                        if (Convert.ToString(col.Trim()).ToLower() == "latitude")
                        col = "lat";
                        if (Convert.ToString(col.Trim()).ToLower() == "longitude")
                        col = "lon";
                        dt.Columns[i].ColumnName = col;
                    }
                    dt.AcceptChanges();
                }
                return dt;
            }
        }
    } catch (Exception)
    {
        throw;
    }
    finally
    {
    }
}

该函数需要两个参数,一个是需要执行的查询,另一个是连接。在这里,我将此源用于 Hi Maps,正如你们所知,为加载地图提供经纬度很重要。所以我在那里进行了此类格式化。

格式化完成后,我可以将数据转换为 JSON 格式。为此,我使用了另一个函数。您可以在下方看到该函数。

public string GetJsonWithZeroForNull(DataTable dt)
{
    try
    {
        if (dt == null)
        {
            throw new ArgumentNullException("dt");
        }
        System.Web.Script.Serialization.JavaScriptSerializer serializer = new
        System.Web.Script.Serialization.JavaScriptSerializer();
        serializer.MaxJsonLength = int.MaxValue;
        List < Dictionary < string, object >> rows =
        new List < Dictionary < string, object >> ();
        Dictionary < string, object > row = null;
        foreach(DataRow dr in dt.Rows)
        {
            row = new Dictionary < string, object > ();
            foreach(DataColumn col in dt.Columns)
            {
                if (dr[col] == null || Convert.ToString(dr[col]).ToLower() == "undefined" ||
                Convert.ToString(dr[col]).ToLower() == "unknown")
                continue;
                else row.Add(col.ColumnName.Trim(), dr[col]);
            }
            rows.Add(row);
        }
        return serializer.Serialize(rows);
    } catch (Exception)
    {
        throw;
    }
}

在这里,我省略了所有无效的数据。最后,它将序列化我们的行并将数据以 JSON 格式返回。

您可以确定,如果数据量很大,则循环两次数据可能会影响性能。

而且,我们都知道数据读取器比数据适配器好得多。如果您不明白原因,请在此处阅读阅读

2. 使用 ADOMD 数据读取器

现在我们将进入下一部分。请参阅以下函数来完成此操作。

    public string createJsonFromDataReader(string query, string adoMDConnection)
     {
        string readerString = string.Empty;
        try
        {
            List < string > curColumn = new List < string > ();
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            string columnName = string.Empty;
            string fieldVal = string.Empty;
            string prevFieldVal = string.Empty;
            AdomdDataReader rdr;
            using(AdomdConnection conn = new AdomdConnection(adoMDConnection))
            {
                conn.Open();
                using(AdomdCommand cmd = new AdomdCommand(query, conn))
                {
                    //cmd.Properties.Add("ReturnCellProperties", true);
                    rdr = cmd.ExecuteReader();
                    if (rdr != null)
                    {
                        using(JsonWriter myJson = new JsonTextWriter(sw))
                        {
                            myJson.WriteStartArray();
                            while (rdr.Read())
                            {
                                myJson.WriteStartObject();
                                int fields = rdr.FieldCount;
                                for (int i = 0; i < fields; i++)
                                {
                                    if (rdr[i] != null)
                                    {
                                        fieldVal = rdr[i].ToString();
                                        if (i != 0 && rdr[i - 1] != null)
                                        prevFieldVal = rdr[i - 1].ToString();
                                        else prevFieldVal = "First";
                                        if ((fieldVal == null || fieldVal.ToLower().Trim() == "undefined" ||
                                        fieldVal.ToLower().Trim() == "unknown")
                                        && (prevFieldVal == null || prevFieldVal.ToLower().Trim() ==
                                            "undefined" || prevFieldVal.ToLower().Trim() == "unknown"))
                                        {
                                            continue;
                                        } else
                                        {
                                            columnName = rdr.GetName(i).Replace(".[MEMBER_CAPTION]",
                                                "").Trim();
                                            curColumn = columnName.Split(new string[] {                                                "."
                                            },
                                            StringSplitOptions.None).ToList();
                                            columnName = curColumn[curColumn.Count - 1].Replace("[",
                                                "").Replace("]", "");
                                            if (Convert.ToString(columnName.Trim()).ToLower() == "latitude")
                                            columnName = "lat";
                                            if (Convert.ToString(columnName.Trim()).ToLower() == "longitude")
                                            columnName = "lon";
                                            myJson.WritePropertyName(columnName);
                                            myJson.WriteValue(rdr[i]);
                                        }
                                    }
                                }
                                myJson.WriteEndObject();
                            }
                            myJson.WriteEndArray();
                        }
                    } else
                    {
                        return "No Records to display";
                    }
                }
            }
            return sw.ToString();
        } catch (Exception)
        {
            throw;
        } finally
        {
        }
    }

请理解,我已经为 JsonWriter 类创建了一个对象(myJson)。我们的整个过程都基于这个对象。同样,完整的逻辑和格式化条件都基于我的需求。

在这里,我们使用了 JsonWriter 类的内置函数。我们列出它们。

  • WriteStartArray()
  • WritePropertyName()
  • WriteValue()
  • WriteEndObject()
  • WriteEndArray()

您可以看到,我使用一个循环同时完成了格式化和 JSON 的创建,这将提高性能。
在此过程中,我们将值追加到 StringBuilder,最后该函数将以所需格式返回 JSON。

您做到了。太棒了。

请在您的应用程序中使用 StringBuilder 而不是 string。只有在必要时才使用字符串变量。使用字符串变量会在每次为其赋值时创建单独的内存分配。请在此处阅读更多内容。

注意:我实现了这个功能来加载 Highcharts。这就是为什么我这样格式化。请根据您的需求使用自己的格式化。

关注点

ADOMD, ADOMD 数据源到 JSON, ADOMD 单元集到 JSON, ADOMD 数据适配器到 JSON, ADOMD 数据读取器到 JSON。

结论

请不要忘记提供您宝贵的建议。今天的分享就到这里,下次文章再见。

© . All rights reserved.