1

总之,我有一个 SQL 解析器和编辑器,我打算将其集成到我的应用程序中。当我运行以下查询时

select * from sys.sysprocesses;

返回的列之一是byte[]. DataTable然而,当我这样做时,这个专栏很高兴被放入

bindingSource.DataSource = result.DataTable;

并尝试在DataGridView我得到明显的ArgumentException. 在这个位置,最好的方法是在 中将 更改byte[]为 astring以显示DataTable

我可以遍历DataTable并做一些类似的事情

foreach(DataColumn col in dataTable.Columns)
    if (col.DataType == typeof(byte[]))
        foreach (DataRow row in dataTable.Rows)
            row[col] = Encoding.ASCII.GetString((byte[])row[col]); 

但这将尝试将 astring放入byte[]列中,并且不起作用。我可以克隆DataTable然后更改类型,

DataTable dtCloned = dataTable.Clone();
dtCloned.Columns[0].DataType = typeof(String);
foreach (DataRow row in dataTable.Rows)
    dtCloned.ImportRow(row);

但我需要一个转换步骤将其转换byte[]为十六进制字符串。实现我想要的最好和最好最有效的方法是什么?

谢谢你的时间。

4

2 回答 2

2

这就是我最终做到这一点的方式。

public static void PostProcessData(ref DataTable dataTable)
{
    // Convert byte[] columns.
    List<DataColumn> colCollRem = new List<DataColumn>();
    List<DataColumn> colCollAdd = new List<DataColumn>();
    foreach(DataColumn col in dataTable.Columns)
        if (col.DataType == typeof(byte[]))
            colCollRem.Add(col);

    // Remove old add new.
    foreach (DataColumn col in colCollRem)
    {
        int tmpOrd = col.Ordinal;
        string colName = String.Format("{0}(Hex)", col.ColumnName);
        DataColumn tmpCol = new DataColumn(colName, typeof(String));
        dataTable.Columns.Add(tmpCol);
        colCollAdd.Add(tmpCol);
        foreach (DataRow row in dataTable.Rows)
            row[tmpCol] = Utilities.ByteArrayToHexString((byte[])row[col]);
        dataTable.Columns.Remove(col);
        string colNameNew = colName.Replace("(Hex)", String.Empty);
        dataTable.Columns[colName].ColumnName = colNameNew;
        dataTable.Columns[colNameNew].SetOrdinal(tmpOrd);
    }
}

使用此转换

public static string ByteArrayToHexString(byte[] p)
{
    byte b;
    char[] c = new char[p.Length * 2 + 2];
    c[0] = '0'; c[1] = 'x';
    for (int y = 0, x = 2; y < p.Length; ++y, ++x)
    {
        b = ((byte)(p[y] >> 4));
        c[x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
        b = ((byte)(p[y] & 0xF));
        c[++x] = (char)(b > 9 ? b + 0x37 : b + 0x30);
    }
    return new string(c);
}

我希望这对其他人有帮助。

于 2012-09-26T16:42:09.347 回答
1

如果您使用的是 SQL server 2005 或更高版本,您可以使用该master.sys.fn_varbintohexstr函数在查询中进行转换。
例子:

select 
  spid,
  kpid,
  ....
  master.sys.fn_varbintohexstr(sid)
from 
  sys.sysprocesses;

编辑
或者您可以将其包装DataTable在一个处理转换的类中,如下所示:(
这假设您的网格不依赖于DataTable作为数据源)

public class Datasource : IEnumerable
{
    private DataTable _dt;

    public Datasource(DataTable dt)
    {
        _dt = dt;
    }

    public IEnumerator GetEnumerator()
    {
        foreach (DataRow row in _dt.Rows)
        {
            IDictionary<string, object> obj = new ExpandoObject();
            for (int i = 0; i < _dt.Columns.Count; i++)
            {
                var value = row[i];
                if (value is byte[])
                    value = BitConverter.ToString((byte[])value);
                obj[_dt.Columns[i].ColumnName] = value;
            }
            yield return obj;
        }
    }
}

用法:

bindingSource.DataSource = new Datasource(result.DataTable);
于 2012-09-26T15:42:02.130 回答