2012-05-17 70 views
2

將表格數據中的重複列摺疊到列表中的最優雅方式是什麼?將重複的列摺疊到子列表中

例子:我寫了一個SQL查詢,返回行包括除單個差分列重複數據:

FIRST LAST  AGE CAR 
Charles Burns  32 Accord 
Charles Burns  32 Buick 
Charles Burns  32 Lexus 
Anders Hejlsberg 51 Porsche 
Anders Hejlsberg 51 Ferrari 
Anders Hejlsberg 51 Bugatti 
Anders Hejlsberg 51 Pinto 

我閱讀這些使用類似以下內容,然後把它們放入一個CarInfo對象:

while(reader.Read()) { 
    first = reader["first"] 
    last = reader["last"] 
    //... 
} 
var myData = new CarInfo(first, last, ...); 

物體看起來像:

// CarInfo: Need 7 total instances with example data 
string first { get; private set; } 
string last { get; private set; } 
int age { get; private set; } 
string car { get; private set; } 

我想它看起來像:

// CarInfo: Need only 2 instances with example data; 
string first { get; private set; } 
string last { get; private set; } 
int age { get; private set; } 
List<string> cars { get; private set; } 

我當然可以這樣做手工,例如通過挑選形成一個唯一的ID列和檢查,如果他們已經在我的名單(或字典或其他) ,但這似乎很辛苦。 我對LINQ很熟悉,懷疑它可以很好地摺疊這些數據,但對於想到一個確切的方法還不夠熟悉。

回答

1

可以load a DataTable和使用LINQ-To-DataSet。然後,CarInfo實例將使用這些字段進行初始化,並且每個組中的所有汽車都會使用List<String>屬性。

0

昨天我剛剛遇到這個問題,但我使用的是SO所用的美麗的對象映射器Dapper。它採用了「拆分」的方法,在那裏你必須指定要父列從孩子分開列列的列或列表:

List<CarInfo> parent = new List<CarInfo>(); 
CarInfo current = null; 
var q = _conn.Query<CarInfo, string, CarInfo>(sql 
    , (p, c0) => 
    { 
     if (current == null || current.Id != p.Id) 
     { 
      current = p; 
     } 
     current.Cars.Add(c0); 
     parents.Add(current); 
     return current; 
    } 
    , splitOn: "CAR" 
); 
1

你試試Enumerable.GroupBy功能?這是你在找什麼?

class A 
     { 
      public string a; 
      public string b; 
      public A(string x, string y) 
      { 
       a = x; 
       b = y; 
      } 
     } 
     static void Main(string[] args) 
     { 
      A[] tab = { new A("1", "1"), new A("2", "0"), new A("3", "1"), new A("4", "0"), new A("5", "1") }; 
      var g = tab.GroupBy(x => x.b); 
      foreach (var x in g) 
      { 

       foreach (var y in x) 
       { 
        Console.WriteLine(y.a + "/" + y.b); 
       } 
       Console.WriteLine("----"); 
      } 
      Console.ReadKey(); 

     } 

此代碼返回:

{1,1} 
{3,1} 
{5,1} 
-------- 
{2,0} 
{4,0} 

由字段B分組的要素;通過匿名類型有三個領域爲重點

List<CarInfo> cars = 
     (from cRow in tblCars.AsEnumerable() 
      group cRow by new 
      { 
       first = cRow.Field<String>("first"), 
       last = cRow.Field<String>("last"), 
       age = cRow.Field<int>("age") 
      }into CarGroup 
      select new CarInfo() 
      { 
       first = CarGroup.Key.first, 
       last = CarGroup.Key.last, 
       age = CarGroup.Key.age , 
       cars = CarGroup.Select(cRow => cRow.Field<String>("Car")).ToList() 
      }).ToList(); 

以上組: