You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#控制台程序写入XML到SQL Server遇编码切换异常的解决问询

解决EF写入SQL Server XML列时的“无法切换编码”异常

问题原因

C#字符串默认是UTF-16编码,当你把带<?xml version="1.0" encoding="utf-8"?>声明的XML字符串直接传给SQL Server的xml列时,SQL Server会按声明的UTF-8去解析实际是UTF-16的内容,编码不匹配导致抛出XML parsing: line 1, character 38, unable to switch the encoding异常。

解决方案

方案一:移除XML声明中的编码属性

直接修改XML内容,去掉编码声明部分,让SQL Server自动识别字符串的实际编码(UTF-16)。

快速字符串替换

// 简单移除编码声明
string cleanedXml = xmlFileContent.Replace("encoding=\"utf-8\"", "");

// 更严谨的正则替换,避免误匹配其他内容
cleanedXml = System.Text.RegularExpressions.Regex.Replace(
    xmlFileContent, 
    @"encoding=""utf-8""", 
    "", 
    System.Text.RegularExpressions.RegexOptions.IgnoreCase
);

之后用处理后的cleanedXml替换原内容写入即可。

用XML解析器处理(更可靠)

通过XmlDocument加载XML后重新生成编码匹配的内容:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlFileContent);

XmlWriterSettings settings = new XmlWriterSettings
{
    OmitXmlDeclaration = false,
    Encoding = Encoding.Unicode // 与C#字符串编码保持一致
};

using (StringWriter sw = new StringWriter())
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
    doc.WriteTo(writer);
    writer.Flush();
    string cleanedXml = sw.ToString();
    // 此时cleanedXml的编码声明为utf-16,可直接写入
}

方案二:使用SqlCommand直接写入(已验证有效)

绕开EF的自动处理逻辑,用参数化SqlCommand写入,SQL Server会正确识别XML参数的编码:

public void WriteXmlTestFileToDatabase(string xmlFileContent)
{
    string connectionString = "你的数据库连接字符串";
    using (SqlConnection conn = new SqlConnection(connectionString))
    {
        conn.Open();
        string sql = "INSERT INTO stor.myTable (FileGuid, XmlDocument) VALUES (@FileGuid, @XmlDocument)";
        using (SqlCommand cmd = new SqlCommand(sql, conn))
        {
            cmd.Parameters.Add("@FileGuid", SqlDbType.VarChar, 36).Value = Guid.NewGuid().ToString();
            // 指定参数类型为SqlDbType.Xml,自动处理编码匹配
            cmd.Parameters.Add("@XmlDocument", SqlDbType.Xml).Value = xmlFileContent;
            cmd.ExecuteNonQuery();
        }
    }
}

方案三:改用XDocument作为EF实体属性类型

EF对XDocument类型的支持更友好,会自动处理XML编码转换:

  1. 修改实体类属性类型:
public partial class myTable
{
    public long myTableId { get; set; }
    public string FileGuid { get; set; }
    public XDocument XmlDocument { get; set; } // 替换原字符串类型
}
  1. 读取XML文件时直接加载为XDocument:
XDocument xmlDoc = XDocument.Load("目标XML文件路径");
WriteXmlTestFileToDatabase(xmlDoc);
  1. 调整写入方法:
public void WriteXmlTestFileToDatabase(XDocument xmlDoc)
{
    using (SqlServerDatabaseEntities db = new SqlServerDatabaseEntities())
    {
        var newEntry = new myTable();
        newEntry.FileGuid = Guid.NewGuid().ToString();
        newEntry.XmlDocument = xmlDoc;

        db.myTable.Add(newEntry);
        db.SaveChanges();
    }
}

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 00:33:16