Column 'size'不可为null需用DBNull替代——C#游戏补丁器代码报错求助
Cabal Online补丁器启动器XML读取代码调试问题
我在调试一段用于Cabal Online游戏补丁器/启动器的C#代码时遇到问题,代码如下:
public void ReadXML() { if (!File.Exists("files.xml")) { return; } //if not exist return creatTable(); using (XmlReader reader = XmlReader.Create("files.xml")) { reader.ReadToFollowing("critical"); DataRow Row; do { Row = downloads_info.NewRow(); reader.MoveToFirstAttribute(); Row["path"] = reader.GetAttribute("path"); Row["hash"] = reader.GetAttribute("hash"); var size = reader.GetAttribute("size"); // get the data value if (size == null) { // if no value, then replace with the SQL required null value size = DBNull.Value; } Row["size"] = size; downloads_info.Rows.Add(Row); } while (reader.ReadToFollowing("critical")); } calc_downloads(); }
运行时出现来自Delegate.cs的报错信息:
[SecuritySafeCritical] protected virtual object
DynamicInvokeImpl(object[] args) { RuntimeMethodInfo
runtimeMethodInfo =
(RuntimeMethodInfo)RuntimeType.GetMethodBase(methodHandle: new
RuntimeMethodHandleInternal(GetInvokeMethod()), reflectedType:
(RuntimeType)GetType()); return runtimeMethodInfo.UnsafeInvoke(this,
BindingFlags.Default, null, args, null); }
我是C#编程新手,希望解决此问题并理解这段代码的逻辑。
问题分析与解决方法
代码逻辑拆解
- 这段代码核心功能是读取
files.xml中的<critical>节点数据,将每个节点的path(文件路径)、hash(文件校验值)、size(文件大小)属性存入downloads_info数据表,最后调用calc_downloads()计算下载相关的统计数据。 - 执行流程:先检查XML文件是否存在,不存在则直接返回;调用
creatTable()创建数据表结构;通过XmlReader遍历所有<critical>节点,逐个提取属性值生成DataRow,再添加到DataTable中。
- 这段代码核心功能是读取
报错根源排查
- 你看到的Delegate.cs代码是底层调用栈片段,不是直接错误原因,需要结合完整异常信息(比如异常类型、上层调用栈)定位,常见触发场景:
- 数据表结构不兼容:
creatTable()创建的downloads_info中,size列若定义为数值类型(如int/long),直接赋值字符串或DBNull.Value会触发类型不匹配异常。 - XML格式异常:
files.xml中的<critical>节点无属性,或属性格式错误,导致reader.MoveToFirstAttribute()或GetAttribute()执行失败。 - 跨线程调用问题:若这段代码在非UI线程操作UI绑定的DataTable控件,会触发委托调用的安全权限异常。
- 数据表结构不兼容:
- 你看到的Delegate.cs代码是底层调用栈片段,不是直接错误原因,需要结合完整异常信息(比如异常类型、上层调用栈)定位,常见触发场景:
针对性修复步骤
- 修正数据表列定义:确保
downloads_info的size列设为可空数值类型(如long?),或允许存储Null值的数值列。 - 优化size赋值逻辑:避免类型不匹配问题:
long? sizeValue = null; var sizeStr = reader.GetAttribute("size"); if (!string.IsNullOrEmpty(sizeStr) && long.TryParse(sizeStr, out long size)) { sizeValue = size; } Row["size"] = sizeValue ?? DBNull.Value; - 增加读取安全校验:防止无属性节点导致的读取异常:
// 在reader.MoveToFirstAttribute()前添加 if (!reader.HasAttributes) { continue; // 跳过无属性的无效节点 } reader.MoveToFirstAttribute(); - 捕获完整异常信息:添加try-catch块输出详细错误,方便精准定位:
public void ReadXML() { try { // 原代码内容 } catch (Exception ex) { Console.WriteLine($"错误详情:{ex.Message}\n调用栈:{ex.StackTrace}"); // 也可写入日志文件或弹窗提示 } }
- 修正数据表列定义:确保
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

