代码改变世界

LINQ TO SQL学习笔记(6)_常见异常及解决办法

2009-05-25 18:11  宗哥  阅读(3398)  评论(0编辑  收藏  举报

LINQ TO SQL学习笔记(6)_常见异常及解决办法

引言

网上介绍Linq TO SQL的资料不少,但是实际工程中的例子很少,本文是我在使用Linq TO SQL开发项目中遇到的异常及解决方法,希望对您有帮助.
本文会继续更新...

系统环境

  1. Visual Studio 2008 NET Framework 3.5+Microsoft SQL Server 2005+Window XP+ SP3
  2. LINQ TO SQL采用配置式开发

常见异常

    本文基本上使用断开的DataContext方式下开发中出现的异常。

  1. [System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException]: {"对象的当前状态使该操作无效。"}
    1. 在使用断开方式的DataContext时候,如果当前对象没有序列化,会产生此异常。
    2. 解决办法:生成Map文件时候序列化参数选择'Unidirectional' 如下:
      sqlMetal /conn:server=.;database=ERP;uid=sa;pwd=Mypass800624 /code:D:\ERP.cs /Map:D:\ERP.map /namespace:DMN /serialization:Unidirectional
    3. 产生原因:断开模式下,对象要进行Attach对象上下文中才能进行Save操作,就是说要以流的形式进行数据表达,因此如果对象没有序列化,就是出现此异常
  2. [System.Runtime.Serialization.SerializationException]: {"类型的对象图包含循环,如果禁用引用跟踪,择无法对其进行序列化。"}
    1. 在使用断开方式的DataContext时候,在递归保存对象的时候,如果子对象没有序列化,会发生此异常
    2. 解决办法:同上
    3. 产生原因:断开模式下,对象进行递归Save操作时候,子对象要先Detach下来然后Attach上去,,就是说要以流的形式进行数据表达,因此如果子对象没有序列化,就是出现此异常
  3. [System.InvalidOperationException]: {"如果实体声明了版本成员或者没有更新检查策略,则只能将它附加为没有原始状态的已修改实体。"}
    1. 在使用断开方式的DataContext时候,在进行对象Save的的时候,如果该对象有Key,而Map文件中没有版本策略声明会有此异常
    2. 解决办法:实际上这是个管理并发冲突的机制,可参考:微软的官方文档 我的解决办法在Map文件中Key加上IsVersion属性,因为我的主键为数据库的自动标示,如下:
        <column name="ID" member="ID" storage="_ID" dbtype="Int NOT NULL IDENTITY" isprimarykey="true" isdbgenerated="true" autosync="OnInsert" isversion="true" />
    3. 产生原因:断开模式下,对象进行递归Save操作时候,如果该对象有Key,系统又找不到记这个对象被Modified过的策略,产生此异常。
  4. 未将对象引用设置到对象的实例。
    1. 使用方式我举个例子:
      string prece = " InDate >= DateTime.Parse(\"2008-08-09\")";         
      IList
      <Student> pp = LQDB.Where(prece);
      var source 
      = from s in pp
                   select 
      new { s.ID, s.Name, s.IDO, s.InDate, s.FromSchool, NO = s.AMClass == null ? "" : s.AMClass.NO, ChargePMName = s.AMClass == null ? "" : s.AMClass.ChargePMName, RoomName =s.AMClass == null ?"": s.AMClass.RoomName, s.MB };
      其中pp是我选择的学生集合, 我重新组合,通过 NO = s.Class.NO得到学生班级编号,结果有的学生还没有分班(我们外包培训基地,业务比较特殊)导致班级 s.Class为Null
    2. 解决办法:Null检查,我的解决办法,如下:
      ' var source = from s in pp select new { s.ID, s.Name, s.IDO, s.InDate, s.FromSchool, NO = s.AMClass == null ? "" : s.AMClass.NO};
    3. 产生原因:学生的类的Class为null,当然对Class的No引用就是产生此异常。
;