2015-11-19 265 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; 
       } 
      }