1

すべて、アプリケーションに統合する予定のSQLパーサーとエディターがあります。次のクエリを実行すると

select * from sys.sysprocesses;

返される列の1つはのタイプですbyte[]。このコラムは喜んで入れられますがDataTable、私がそうすると

bindingSource.DataSource = result.DataTable;

そして、データを表示しようとするとDataGridView、明らかArgumentExceptionです。この位置で、を表示byte[]するためにに変更する最良の方法は何ですか?stringDataTable

私はループして、次の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]); 

ただし、これは列にを入れようとし、機能stringbyte[]ません。クローンを作成してDataTableからタイプを変更できます。

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

byte[]しかし、を16進文字列に変換するための変換ステップが必要です。私が望むことを達成するための最良の、そしてできれば最も効率的な方法は何ですか?

御時間ありがとうございます。

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;

編集または、次のように変換を処理するクラスで
ラップすることもできます: (これは、グリッドがas データソース を持つことに依存していないことを前提としています)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 に答える