将DataTable中的列值从byte []转换为String

时间:2012-09-26 14:45:23

标签: c# types datagridview casting datatable

全部,我有一个SQL Parser和编辑器,我打算在我的应用程序中集成。当我运行以下查询

select * from sys.sysprocesses;

返回的列之一是byte[]类型。我很高兴地将这一栏放入DataTable,但是,当我这样做时

bindingSource.DataSource = result.DataTable;

并尝试在DataGridView中显示数据我明显ArgumentException。在这个位置,最好的方法是将byte[]更改为string以便在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]); 

但是这会尝试将string放入byte[]列,但无效。我可以克隆DataTable然后更改类型

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

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

感谢您的时间。

2 个答案:

答案 0 :(得分: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);
}

我希望这有助于其他人。

答案 1 :(得分: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);