为何SQL Server的XML类型列在.NET中通过SqlDataReader/SqlDataAdapter读取为字符串?
解决SQL Server XML列在.NET中被识别为字符串的问题
以下是几种可靠的方案,帮你识别XML类型结果并仅在必要时转换:
1. 使用SqlDataReader直接读取并判断类型
SqlDataReader可以直接获取列的原生SQL类型,你可以先检查列的SqlDbType是否为Xml,再用GetSqlXml方法读取,避免自动转为字符串:
using (SqlCommand sc = new SqlCommand("select *, convert(xml, c1) c6 from tempdb..t1", conn)) { conn.Open(); using (SqlDataReader reader = sc.ExecuteReader()) { while (reader.Read()) { for (int i = 0; i < reader.FieldCount; i++) { if (reader.GetSqlDbType(i) == SqlDbType.Xml && !reader.IsDBNull(i)) { // 读取为SqlXml对象,可进一步转为XmlDocument或XElement SqlXml sqlXml = reader.GetSqlXml(i); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(sqlXml.CreateReader()); // 使用xmlDoc处理XML数据 } else { // 处理其他类型数据,直接读取即可 object value = reader[i]; } } } } }
2. 给DataTable预定义列类型(适配SqlDataAdapter)
如果必须用SqlDataAdapter填充DataTable,可先手动创建DataTable的列并指定XML列的类型为XmlDocument(或XElement),这样填充时会自动映射为XML对象:
using (SqlCommand sc = new SqlCommand("select *, convert(xml, c1) c6 from tempdb..t1", conn)) { DataTable dt = new DataTable(); // 先通过SqlDataReader获取列元数据,手动创建列 using (SqlDataReader reader = sc.ExecuteReader(CommandBehavior.SchemaOnly)) { foreach (DataRow schemaRow in reader.GetSchemaTable().Rows) { string colName = schemaRow["ColumnName"].ToString(); SqlDbType sqlType = (SqlDbType)schemaRow["ProviderType"]; DataColumn column = new DataColumn(colName); // 判断是否为XML类型,指定对应.NET类型 if (sqlType == SqlDbType.Xml) { column.DataType = typeof(XmlDocument); } else { // 其他类型自动映射对应.NET类型 column.DataType = Type.GetType(schemaRow["DataType"].ToString()); } dt.Columns.Add(column); } } // 填充DataTable new SqlDataAdapter(sc).Fill(dt); // 此时XML列的数据类型为XmlDocument,无需额外转换 }
3. 填充后检查DataTable列类型并转换
如果已经填充了DataTable,可遍历列检查ProviderType是否为SqlDbType.Xml,再批量转换该列的字符串内容为XML对象:
DataTable dt = new DataTable(); new SqlDataAdapter(sc).Fill(dt); foreach (DataColumn col in dt.Columns) { // 检查列是否为SQL XML类型 if (col.ProviderType == SqlDbType.Xml) { foreach (DataRow row in dt.Rows) { if (row[col] != DBNull.Value) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(row[col].ToString()); row[col] = xmlDoc; } } } }
内容的提问来源于stack exchange,提问作者elle0087
相关产品推荐
相关产品推荐

