2013-01-08 32 views
-1

我正在使用LINQ to SQL獲取數據集。我需要過濾以下數據集:基於涉及其他行的條件過濾LINQ to SQL集合

如果存在空SourceName的字段,並且該字段的至少一個其他記錄具有非空SourceName,則應將其刪除。

如果它是該字段的唯一行,那麼它應該保留在列表中。

下面是一個例子數據:數據由3列: '字段', 'SOURCENAME' 和 '速度'

Field | SourceName | Rate 
10 | s1  | 9 
10 | null | null 
11 | null | null 
11 | s2  | 5 
11 | s3  | 4 
12 | null | null 
13 | null | null 
13 | s4  | 7 
13 | s5  | 8 
    8 | s6  | 2 
    9 | s7  | 23 
    9 | s8  | 9 
    9 | s9  | 3 

輸出應該是這樣的:

Field | SourceName | Rate 
10 | s1  | 9 
11 | s2  | 5 
11 | s3  | 4 
12 | null  | null // <- (remains since there's only 
13 | s4  | 7  //  1 record for this 'Field') 
13 | s5  | 8 
    8 | null  | null 
    9 | s8  | 9 
    9 | s9  | 3  

如何過濾它?

+0

什麼是對象類型?通常你可以使用類似的過濾器來過濾一個集合:'filteredList = unfilteredList.Where(i => i.SourceName!= null);' – David

+0

@David - 我想這是無法完成的。這將刪除任何具有空源名稱的行。如果它是數據集中唯一的一行,我希望該行保留。謝謝你的評論。 – Aqua267

+0

@Veena:然後是一個更復雜的Where子句,但過程依然如此。可能類似於:'.Where(i =>(i.SourceName!= null)||((i.SourceName == null)&&(unfilteredList.Where(j => j.Field == i.Field).Count ()== 1)))'這都是徒手畫,所以它可能不完美,但它應該給你一個想法。 – David

回答

0

使用LINQ內置的「位置」是lambda延續子句:使用lambda的和一個簡單的POCO類的數據存儲在你們這樣一個名單的

簡單的靜態例如:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace Simple 
{ 
    class Program 
    { 
     class Data 
     { 
      public string Field { get; set; } 
      public string SourceName { get; set; } 
      public string Rate { get; set; } 
     } 

     static List<Data> Create() 
     { 
      return new List<Data> 
       { 
        new Data {Field = "10", SourceName = null, Rate = null}, 
        new Data {Field = "11", SourceName = null, Rate = null}, 
        new Data {Field = "11", SourceName = "s2", Rate = "5"} 
       }; 
     } 

     static void Main(string[] args) 
     { 
      var ls = Create(); 

      Console.WriteLine("Show me my whole list: \n\n"); 

      // write out everything 
      ls.ForEach(x => Console.WriteLine(x.Field + "\t" + x.SourceName + "\t" + x.Rate + "\n")); 


      Console.WriteLine("Show me only non nulls: \n\n"); 

      // exclude some things 
      ls.Where(l => l.SourceName != null) 
       .ToList() 
       .ForEach(x => Console.WriteLine(x.Field + "\t" + x.SourceName + "\t" + x.Rate + "\n")); 

      Console.ReadLine(); 
     } 
    } 
} 
1

什麼你試圖達到的不是微不足道的,只用.Where()條款就無法解決。您的篩選條件取決於需要分組的條件,因此您必須使用.GroupBy(),然後使用.SelectMany()將收集的集合平鋪。

下面的代碼滿足您使用LINQ to Objects的預期輸出,並且我沒有看到任何LINQ to SQL不能將其轉換爲SQL的原因,也沒有嘗試過這種困難。

 //Group by the 'Field' field. 
yourData.GroupBy(x => x.Field) 

     //Project the grouping to add a new 'IsUnique' field 
     .Select(g => new { 
         SourceAndRate = g, 
         IsUnique = g.Count() == 1, 
     }) 

     //Flatten the collection using original items, plus IsUnique 
     .SelectMany(t => t.SourceAndRate, (t, i) => new { 
         Field = t.SourceAndRate.Key, 
         SourceName = i.SourceName, 
         Rate = i.Rate, 
         IsUnique = t.IsUnique 
     }) 

     //Now we can do the business here; filter nulls except unique 
     .Where(x => x.SourceName != null || x.IsUnique);