LINQ的左外连接列选择

时间:2010-07-29 18:16:21

标签: c# linq

我有一个来自数据集ds的三个表。

var test0 = from a in ds.Tables[0].AsEnumerable()
            select a["ID"].ToString();

test0具有以下值 -

  [0] "8" 
  [1] "9" 
  [2] "11" 
  [3] "2" 
  [4] "1"

var test1 = from a in ds.Tables[1].AsEnumerable()
            select a["SubscriptionID"].ToString();

test1有这些 -

  [0] "25" 
  [1] "27" 
  [2] "4" 
  [3] "26" 
  [4] "5" 
  [5] "6" 
  [6] "1" 
  [7] "24" 
  [8] "23" 
  [9] "2" 
  [10] "9" 

var comTable1 =
  from a in ds.Tables[0].AsEnumerable()
  from b in ds.Tables[1].AsEnumerable()
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString())
    .DefaultIfEmpty()
  select b;

comTable1返回这些正确的值 -

   [0] null  
   [1] {System.Data.DataRow}  
   [2] null  
   [3] {System.Data.DataRow}  
   [4] {System.Data.DataRow}

对我来说问题是,如果我想选择特定字段,它将抛出一条消息“对象引用未设置为对象的实例”。在comTable2中使用以下代码 -

var comTable2 =
  from a in ds.Tables[0].AsEnumerable()
  from b in ds.Tables[1].AsEnumerable()
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString())
    .DefaultIfEmpty()
  select b["SubscriptionID"];

为什么LINQ中的左连接不返回其他无空值?有没有办法避免这种情况?

我问这个是因为我的代码需要继续与其他表连接,例如 -

var comTable =
  from a in ds.Tables[0].AsEnumerable()
  from b in ds.Tables[1].AsEnumerable()
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString())
    .DefaultIfEmpty()
  from c in ds.Tables[2].AsEnumerable()
    .Where(cc => cc["ID"].ToString() == (b["GroupID"]??"null").ToString())
    .DefaultIfEmpty()
  select c;

现在我无法从b和c获得任何东西。

谢谢!

1 个答案:

答案 0 :(得分:3)

是的 - 如果您尝试取消引用空值,获得异常。试试这个:

var comTable2 = from a in ds.Tables[0].AsEnumerable()
                from b in ds.Tables[1]
                            .AsEnumerable()
                            .Where(bb => bb["SubscriptionID"].ToString() 
                                   == a["ID"].ToString())
                            .DefaultIfEmpty()
                select b == null ? null : b["SubscriptionID"];

基本上,最后的条件表达式将在没有匹配的情况下保留空值,如果没有,则保留订阅ID。

在较大的查询中,您仍需要处理b null的可能性。你肯定在这里想要一个左外连接,而不是LINQ连接子句给出的内连接吗?