全部,我有一个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[]
转换为十六进制字符串。什么是实现我想要的最好,最有效的方式?
感谢您的时间。
答案 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);