当在联合表上使用Where子句时,左连接Linq查询

时间:2016-10-20 12:04:58

标签: c# linq

我可以看到这个问题已被问过几次,但我很困惑如何为自己实施。

我正在使用SQL Lite,我正在尝试加入2个表,但有时第2个表中的“链接”行不存在。

这是我的代码:

return from address in DB.Connector.Table<InformedWorkerModel.Tables.Address>()
       join addressHistory in DB.Connector.Table<InformedWorkerModel.Tables.AddressHistory>() 
       on address.AddressRef equals addressHistory.AddressRef 
       where addressHistory.CustomerRef == customerRef 
       select new InformedWorkerModel.Tables.Address
       {
           Address1 = address.Address1,
           Address2 = address.Address2,
           Address3 = address.Address3,
           Town = address.Town,
           County = address.County,
           Country = address.Country,
           PostCode = address.PostCode,
           AddressRef = address.AddressRef,
           AddressId = address.AddressId
       };

在谷歌搜索我可以看到一个解决方案,如果我不使用'where'条款..但我... ..

2 个答案:

答案 0 :(得分:1)

您错过了DefaultIfEmpty()部分的使用,这就是将其转换为左连接(查看文档 - 它非常清楚如何执行所有不同的连接)

   from address in DB.Connector.Table<InformedWorkerModel.Tables.Address>()
   join addressHistory in (from x in DB.Connector.Table<InformedWorkerModel.Tables.AddressHistory>() 
                           where x.CustomerRef == customerRef
                           select x) 
   on address.AddressRef equals addressHistory.AddressRef into j
   from addressHistory in j.DefaultIfEmpty()
   select new InformedWorkerModel.Tables.Address
   {
       Address1 = address.Address1,
       Address2 = address.Address2,
       Address3 = address.Address3,
       Town = address.Town,
       County = address.County,
       Country = address.Country,
       PostCode = address.PostCode,
       AddressRef = address.AddressRef,
       AddressId = address.AddressId
   };

另见我将addressHistory.CustomerRef == customerRef移动到嵌套选择。如果您不这样做,那么您将只获得具有该值的行 - 有效地将其转换为“正常”inner join 。 另一种方式就像之前一样但是:

where addressHistory == null || addressHistory.CustomerRef == customerRef

所以它看起来像:

   from address in DB.Connector.Table<InformedWorkerModel.Tables.Address>()
   join addressHistory in DB.Connector.Table<InformedWorkerModel.Tables.AddressHistory>() 
   on address.AddressRef equals addressHistory.AddressRef into j
   from addressHistory in j.DefaultIfEmpty()
   where addressHistory == null || addressHistory.CustomerRef == customerRef
   select new InformedWorkerModel.Tables.Address
   {
       Address1 = address.Address1,
       Address2 = address.Address2,
       Address3 = address.Address3,
       Town = address.Town,
       County = address.County,
       Country = address.Country,
       PostCode = address.PostCode,
       AddressRef = address.AddressRef,
       AddressId = address.AddressId
   };

答案 1 :(得分:1)

如果你想要返回数据,即使这个地址的addressHistory表中没有行,那么你需要做一个等同的SQL“左连接”:

join addressHistory in DB.Connector.Table<InformedWorkerModel.Tables.AddressHistory>()
     on address.AddressRef equals addressHistory.AddressRef
     into joinedAddressHistories
     from joinedHistory in joinedAddressHistories.DefaultIfEmpty()

但是,您还需要修改where条款,因为如果您尝试,现在会失败:

where joinedHistory.CustomerRef = customerRef

由于joinedHistory将为null。如果不知道你想要什么,我无法提出解决方案。