Linq中的陷阱问题(折磨了好几天)

简介: Linq2SQL中一个经典的Exception Info: System.Data.Linq.ChangeConflictException异常过程。

最近在程序运行中,发生一个比较怪异的问题导致程序异常退出(崩溃),开始没注意,以为是偶发问题。后来变成了必再现问题。查看Windows事件日志异常如下:

Application: XXXXX.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Data.Linq.ChangeConflictException
Stack:
   at System.Data.Linq.DataContext.SubmitChanges(System.Data.Linq.ConflictMode)
   at NMS.PPC.DataSource.Database.DBOperator.SubmitChanges()

开始也没在意。觉得这个没什么,就是数据库更新时异常了。加个try-catch就解决了。结果发现另一个功能也发生了这个问题。由于Windows日志中没有抛出具体的Message,使用WinDebug分析Dump文件,看到了具体的消息,如下:

Exception object: 0000000010f87f48
Exception type:   System.Data.Linq.ChangeConflictException
Message:          找不到行或行已更改。
InnerException:   <none>

要更新的行明明存在怎么能找不到。我没更改呢,所以已更改不太可能发生。
因为研发环境无法再现,就将测试环境中的数据库和数据拿回到研发环境中,很快就再现了。确定问题确实存在。通过Linq输出SQL语句,发生所有的字段都在Where条件中出现了(这可能是Linq慢的原因吧)。
然后百度找到https://stackoverflow.com/questions/11189688/linq-to-sql-updating-without-refresh-when-updatecheck-never,说在Linq设计器将表列设置上UpdateCheck = Never。我是直接编码的,不用设计器。通过在DEMO程序中添加一个Linq设计,发现些设置在代码中就是在Column属性中加一个UpdateCheck即可。

[Column(UpdateCheck = UpdateCheck.Never)]
public double? AField{get;set;}

然后分析为什么旧的数据为什么出现,而新数据不出现。在分析崩溃原因时先不进行UpdateCheck = Never的设置。发现所有可空字段没设置值在Where条件中都是Is NULL判断。但AField却是=判断,但数据库中却没有值(将实例类字段值全输出发现AFiled居然有值)。
这个问题原因就找到了,确实按照Where条件查询不到记录了,异常也发生了。
然后到Linq实体类中去找代码,如下(代码中相关属性设置没添加):

private double? _AField;
public double? AField{
    get{
        if (_AFiled == null) return BField;
        return _AFiled;
    }
}

终于找到了原因,当AFiled是NULL时,直接取BField的值了,程序中确实对BField赋值了。
然后发现出问题的数据都是在此代码提交之前产生的数据,提交之后产生的数据正常。
总结
Linq2SQL中,如果是计算列,不用持久化到数据库中。所以可以不用加Column这个Attribute。
Linq2SQL中,Update时默认会把所有的持久化字段(即添加了Column这个Attribute的字段)作为Where条件,如果是在发布后的程序中添加新的非主键字段,建议在Column中添加上UpdateCheck = UpdateCheck.Never,这样在发布后更新旧的数据不会发生这种莫名的异常。

目录
相关文章
|
9天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
3908 19
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
11天前
|
人工智能 自然语言处理 供应链
|
17天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3631 14
|
13天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
3067 7
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
20天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3772 25
|
4天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
538 0