2015-11-19 132 views
1

我一直在使用这个linq查询一段时间。我看了很多关于stackoverflow和以后的答案。我已经尝试了很多解决方案并阅读了很多。下面的代码是我无数次尝试建立这种内在的2加入,我得到的错误是Linq左外部连接C#

对象引用未设置到对象的实例

尝试

var records = from cr in lstContactResponse 
    join jn in lstJourneyNodeData on cr.GrandparentId equals jn.Id into a 
    from x in a.DefaultIfEmpty() 
    join j in lstJourney on x.JourneyId equals j.Id into b 
    from y in b.DefaultIfEmpty() 
    join ce in lstCampaignElement on y.Name equals ce.LinkedJourney into c 
    from z in c.DefaultIfEmpty() 
    join c in lstCampaign on z.CampaignId equals c.Id into d 
    from w in d.DefaultIfEmpty() 
    select new JourneyRecord 
    { 
     CompanyName = w.Company, 
     BrandName = w.Brand, 
     CampaignName = w.Name, 
     Channel = z.Type, 
     Wave = "", 
     CampaignId = w.Id, 
     ActivityDate = cr.ResponseDate, 
     Activity = "", 
     Unsubscribed = cr.Unsubscribed, 
     Responded = cr.Responded, 
     Clicked = cr.Clicked, 
     Viewed = cr.Viewed, 
     Sent = cr.Sent, 
     Targeted = cr.Targeted, 
     HardBounced = cr.HardBounced, 
     SoftBounced = cr.SoftBounced, 
     WasTargeted = cr.WasTargeted, 
     Email = "", 
     Id = "", 
     CampaignElementId = z.Id, 
     CampaignWaveId = "J" + x.Id, 
     ContactId = cr.ContactId, 
     AtTaskId = w.AtTaskId, 
     LinkClicked = cr.Referrer, 
     OptTopic = z.TopicId, 
     DiseaseState = "", 
     ElementDescription = y.Name, 
     WaveDescription = x.Label 
    }; 

尝试乙

var records = from cr in lstContactResponse 
    join jn in lstJourneyNodeData on cr.GrandparentId equals jn.Id into a 
    from x in a.DefaultIfEmpty() 
    join j in lstJourney on x.JourneyId equals j.Id into b 
    from y in b.DefaultIfEmpty() 
    join ce in lstCampaignElement on y.Name equals ce.LinkedJourney into c 
    from z in c.DefaultIfEmpty() 
    join c in lstCampaign on z.CampaignId equals c.Id into d 
    from w in d.DefaultIfEmpty() 
    select new JourneyRecord 
    { 
     CompanyName = x == null ? null : w.Company, 
     BrandName = x == null ? null : w.Brand, 
     CampaignName = x == null ? null : w.Name, 
     Channel = x == null ? null : z.Type, 
     Wave = "", 
     CampaignId = x == null ? null : w.Id, 
     ActivityDate = x == null ? null : cr.ResponseDate, 
     Activity = "", 
     Unsubscribed = x == null ? null : cr.Unsubscribed, 
     Responded = x == null ? null : cr.Responded, 
     Clicked = x == null ? null : cr.Clicked, 
     Viewed = x == null ? null : cr.Viewed, 
     Sent = x == null ? null : cr.Sent, 
     Targeted = x == null ? null : cr.Targeted, 
     HardBounced = x == null ? null : cr.HardBounced, 
     SoftBounced = x == null ? null : cr.SoftBounced, 
     WasTargeted = x == null ? null : cr.WasTargeted, 
     Email = "", 
     Id = "", 
     CampaignElementId = x == null ? null : z.Id, 
     CampaignWaveId = "J" + (x == null ? null : x.Id), 
     ContactId = x == null ? null : cr.ContactId, 
     AtTaskId = x == null ? null : w.AtTaskId, 
     LinkClicked = x == null ? null : cr.Referrer, 
     OptTopic = x == null ? null : z.TopicId, 
     DiseaseState = "", 
     ElementDescription = x == null ? null : y.Name, 
     WaveDescription = x == null ? null : x.Label 
    }; 

尝试ç

var records = from cr in lstContactResponse 
    join jn in lstJourneyNodeData on cr.GrandparentId equals jn.Id into a 
    from x in a.DefaultIfEmpty() 
    join j in lstJourney on x.JourneyId equals j.Id into b 
    from y in b.DefaultIfEmpty() 
    join ce in lstCampaignElement on y.Name equals ce.LinkedJourney into c 
    from z in c.DefaultIfEmpty() 
    join c in lstCampaign on z.CampaignId equals c.Id into d 
    from w in d.DefaultIfEmpty() 
    select new JourneyRecord 
    { 
     CompanyName = w == null ? null : w.Company, 
     BrandName = w == null ? null : w.Brand, 
     CampaignName = w == null ? null : w.Name, 
     Channel = z == null ? null : z.Type, 
     Wave = "", 
     CampaignId = w == null ? null : w.Id, 
     ActivityDate = cr == null ? null : cr.ResponseDate, 
     Activity = "", 
     Unsubscribed = cr == null ? null : cr.Unsubscribed, 
     Responded = cr == null ? null : cr.Responded, 
     Clicked = cr == null ? null : cr.Clicked, 
     Viewed = cr == null ? null : cr.Viewed, 
     Sent = cr == null ? null : cr.Sent, 
     Targeted = cr == null ? null : cr.Targeted, 
     HardBounced = cr == null ? null : cr.HardBounced, 
     SoftBounced = cr == null ? null : cr.SoftBounced, 
     WasTargeted = cr == null ? null : cr.WasTargeted, 
     Email = "", 
     Id = "", 
     CampaignElementId = z == null ? null : z.Id, 
     CampaignWaveId = "J" + (x == null ? null : x.Id), 
     ContactId = cr == null ? null : cr.ContactId, 
     AtTaskId = w == null ? null : w.AtTaskId, 
     LinkClicked = cr == null ? null : cr.Referrer, 
     OptTopic = z == null ? null : z.TopicId, 
     DiseaseState = "", 
     ElementDescription = y == null ? null : y.Name, 
     WaveDescription = x == null ? null : x.Label 
    }; 
+0

尝试围绕与.toList查询()在做任何进一步的操作之前,还要检查“记录”的值 –

+0

我在循环中这样做,以便程序在没有项目时不会崩溃。我甚至无法得到这个,这是查询后的下一行。 'List lstRecords = null;如果(记录!=空&& records.Count()> 0) { lstRecords = records.ToList(); }' – coding

+0

你检查过你的所有列表值吗? –

回答

1

当然是有办法做到这一点的LINQ。如果你在评论中回答了我的问题,我会为你提供确切的解决方案,现在我只给你一个例子。 LINQ to Objects与LINQ to Entities的技术不同,因此以下内容适用于LINQ to Objects。

解决的办法是检查null每一个涉及左边加入的右侧属性,包括的进一步加入。此外值类型属性需要转换为空(这就是为什么重要的是有你的类 - 对于以前的C#6代码)。

这里是例子:

具有下面的 “表格”

var t1 = new[] 
{ 
    new { Id = 1 , Name = "A", Date = DateTime.Today }, 
    new { Id = 2 , Name = "B", Date = DateTime.Today}, 
    new { Id = 3 , Name = "C", Date = DateTime.Today}, 
}; 
var t2 = new[] 
{ 
    new { Id = 1 , ParentId = 1, Name = "A1", Date = DateTime.Today }, 
    new { Id = 2 , ParentId = 2, Name = "B1", Date = DateTime.Today }, 
}; 
var t3 = new[] 
{ 
    new { Id = 1 , ParentId = 1, Name = "A11", Date = DateTime.Today }, 
    new { Id = 2 , ParentId = 1, Name = "A12", Date = DateTime.Today }, 
}; 
var t4 = new[] 
{ 
    new { Id = 1 , ParentId = 1, Name = "A111", Date = DateTime.Today }, 
}; 

前C#6

var query = 
    from e1 in t1 
    join e2 in t2 on e1.Id equals e2.ParentId into g2 
    from e2 in g2.DefaultIfEmpty() 
    join e3 in t3 on e2 != null ? (int?)e2.Id : null equals e3.ParentId into g3 
    from e3 in g3.DefaultIfEmpty() 
    join e4 in t4 on e3 != null ? (int?)e3.Id : null equals e4.Id into g4 
    from e4 in g4.DefaultIfEmpty() 
    select new 
    { 
     t1_Id = e1.Id, 
     t1_Name = e1.Name, 
     t1_Date = e1.Date, 
     t2_Id = e2 != null ? (int?)e2.Id : null, 
     t2_Name = e2 != null ? e2.Name : null, 
     t2_Date = e2 != null ? (DateTime?)e2.Date : null, 
     t3_Id = e3 != null ? (int?)e3.Id : null, 
     t3_Name = e3 != null ? e3.Name : null, 
     t3_Date = e3 != null ? (DateTime?)e3.Date : null, 
     t4_Id = e4 != null ? (int?)e4.Id : null, 
     t4_Name = e4 != null ? e4.Name : null, 
     t4_Date = e4 != null ? (DateTime?)e4.Date : null, 
    }; 
var result = query.ToList(); 

相貌丑陋,但工程。

C#6 - 同样的结果通过任何右侧属性访问之前简单地增加?实现(重复 - 包括连接条件)

var query = 
    from e1 in t1 
    join e2 in t2 on e1.Id equals e2.ParentId into g2 
    from e2 in g2.DefaultIfEmpty() 
    join e3 in t3 on e2?.Id equals e3.ParentId into g3 
    from e3 in g3.DefaultIfEmpty() 
    join e4 in t4 on e3?.Id equals e4.Id into g4 
    from e4 in g4.DefaultIfEmpty() 
    select new 
    { 
     t1_Id = e1.Id, 
     t1_Name = e1.Name, 
     t1_Date = e1.Date, 
     t2_Id = e2?.Id, 
     t2_Name = e2?.Name, 
     t2_Date = e2?.Date, 
     t3_Id = e3?.Id, 
     t3_Name = e3?.Name, 
     t3_Date = e3?.Date, 
     t4_Id = e4?.Id, 
     t4_Name = e4?.Name, 
     t4_Date = e4?.Date, 
    }; 
var result = query.ToList(); 
+0

酷!谢谢!我只是在一段时间内没有得到这个项目。 – coding

0

有没有办法使用LINQ,我是能够确定完成我所想做的事。因此,我采取了解决问题的另一个方向。

foreach (ContactResponse cr in lstContactResponse) 
    { 
    ContactResponseRecord crr = new ContactResponseRecord() { 
               ContactId = cr.ContactId, 
               ActivityDate = cr.ResponseDate, 
               LinkClicked = cr.Referrer}; 


    var vJourneyNodeData = from x in lstJourneyNodeData where x.Id == cr.GrandparentId select x; 
    if(null != vJourneyNodeData && vJourneyNodeData.Count() > 0) 
      { 
       jnd = vJourneyNodeData.FirstOrDefault(); 
       crr.CampaignWaveId = "J" + jnd.Id; 
       crr.WaveDescription = jnd.Label; 
      } 

    var vJourney = from x in lstJourney where x.Id == jnd.JourneyId select x; 
    if (null != vJourney && vJourney.Count() > 0) 
      { 
       j = vJourney.FirstOrDefault(); 
       crr.OptTopic = j.TopicId; 
      } 

    var vCampaignElement = from x in lstCampaignElement where x.LinkedJourney == j.Name select x; 
    if (null != vCampaignElement && vCampaignElement.Count() > 0) 
      { 
       ce = vCampaignElement.FirstOrDefault(); 
       crr.Ccg_Id = ce.CCGId; 
       crr.ElementDescription = ce.Description.ToString(); 
       crr.CampaignElementId = ce.Id; 

     var vCampaign = from x in lstCampaign where x.Id == ce.CampaignId select x; 
     if (null != vCampaign && vCampaign.Count() > 0) 
       { 
        c = vCampaign.FirstOrDefault(); 
        crr.ActivityDate = c.AtTaskId; 
        crr.BrandName = c.Brand; 
        crr.CampaignId = c.Id; 
        crr.CampaignName = c.Name; 
        crr.CompanyName = c.Company; 
       } 
      }