LINQ学习中关于null相关的问题及解决方案

      null词语释义:编程中的NULL表示不可用的数据,没有意义.

       1. 无效的;无价值的

       2. 【数】零的

     Null在数据库中表示 不知道(Unknown) 的数据,主要有3种意思:
          1)知道数据存在,但不知道具体值
          2)不知道数据是否存在
          3)数据不存在

        NULL在数据库中的说明可以参考这篇文章:SQL开发中容易忽视的一些小地方(一)

      "null"这个对象在不同的编程环境下有不同的含义,这里就不多说了,现在想总结下我在学习LINQ时关于处理null的问题.  

      第一:数组元素中的null .有如下一个二维整形数组

 int[][] numbers = {
  
new int[] { 123 },
  
new int[] { 456 },
  
new int[] { 456 }
};

      我们用拉姆达表达式想得到这个二维数组里面的每一个元素构成的列表,我们可以这样写:

IEnumerable<int> list = numbers.SelectMany(c => c);

      SelectMany专门是针对一对多的处理而设计的.一般情况下都应该会正常运行,如果再给numbers增加一个值为null的元素呢?程序还会正常吗?答案是否定的,它会抛出:Object reference not set to an instance of an object.

                
int[][] numbers = {
  
new int[] { 123 },
  
new int[] { 456 },
  
new int[] { 456 },                
  
null
};

      解决方案:利用"??"运算符判断c是否等于null,如果等于则利用Enumerable.Empty返回一个具有指定的类型参数的空,这样在取元素时会跳过元素为空的值。

IEnumerable<int> list = numbers.SelectMany(c => c ?? Enumerable.Empty<int>());

      文中例子说明:

        表名:  Table_2

        列:iScore

        类型:int.

        是否可空:是

      第二:LINQ TO SQL中的Sum.计算成绩大于50的所有成绩总分:运行下面语句时会报异常.

int i = db.Table_2s.Where<Table_2>(t=> t.iScore>50).Sum<Table_2>(t => t.iScore);

 

      分析原因:我们把数据库对象Table_2 放进dbml文件时,列iScore会生成如下代码,看下System.Nullable<int> iScore.,iScore由于要进行Sum运算,而VS默认认为Sum里面的字段都不为空,所以会出错,为点与SQL有区别,SQL在进行汇总时,会忽略null的值。

[Column(Storage="_iScore", DbType="Int")]
        
public System.Nullable<int> iScore

    

      解决方案:

                  1:在可视化生成代码后,手动把Nullable去掉.              

[Column(Storage="_iScore", DbType="Int")]
        
public int iScore

                

                  2:或者在数据库中修改表结构,要求汇总的字段都为非空.

      第三:LINQ TO SQL中,如何来判断一条记录的某个字段值是否等于NULL?计算ID等于NULL且成绩大于50的成绩总分,我们可以这样写:和SQL的唯一区别是,LINQ TO SQL中:t.ID ==null,等号为两个等号,而在SQL中是一个.
  
int i = db.Table_2s.Where<Table_2>(t=>t.ID ==null &&  t.iScore>50).Sum<Table_2>(t => t.iScore);
   
      第四:LINQ 中,我们取一个集合的第一个元素,例如:
 
int[] numbers4  = { 12345 };
 
int b = numbers4.First (n => n > 10);

  

    上面是查询数组中第一个大于10的元素,但上面的语句在执行会报:Sequence contains no elements的提示以及相应的异常.如何避免呢,总不能先Count再判断吧,我们可以利用FirstOrDefault来解决这种问题.如果不存在,会返回一个默认的值,这个值相当于初始化int i;

int a = numbers4.FirstOrDefault(n => n > 10);


    总结:

          1:遍历集合时,最好使用c => c ?? Enumerable.Empty<int>()条件,避免元素为空导致出错;
          2:在对表字段进行汇总求和时,字段要求为非空;
          3:查询表记录时,判断一个字段是否等于NULL,用法和SQL差不多,含义一样;
          4:计算集合第一个元素时,尽量使用FirstOrDefault,避免结果集为空导致程序出错.

          上面是关于NULL在LINQ中和其它语言不太一样的地方,大家如果还有其它的观点可以指教下.

posted on 2008-12-17 15:06  min.jiang  阅读(10062)  评论(7编辑  收藏  举报