2010-02-27 28 views
6

數據標準化假設我們有一些非規範化的數據,這樣的:與LINQ

List<string[]> dataSource = new List<string[]>(); 
string [] row1 = {"grandParentTitle1", "parentTitle1", "childTitle1"}; 
string [] row2 = {"grandParentTitle1", "parentTitle1", "childTitle2"}; 
string [] row3 = {"grandParentTitle1", "parentTitle2", "childTitle3"}; 
string [] row4 = {"grandParentTitle1", "parentTitle2", "childTitle4"}; 
dataSource.Add(row1); 

我需要它正常化,例如獲得IEnumerable < Child>,並填充了Child.Parent和Child.Parent.GrandParent。

重要的方法或多或少都很清楚。與Linq相比,它會更短嗎?

在一個查詢中效果更好,這對於更多實體應該是可擴展的。

我想是這樣單獨創建的IEnumerable <祖父母>,然後IEnumerable的<家長>與分配等

請可在此功能的方式來實現的提示?

+0

你試過Groupby()嗎? – 2010-02-27 21:20:04

+0

問題是如何在沒有重複的情況下創建和鏈接實體。 選擇(新的父母{GrandParent =新的父母}) 或者我錯過了什麼? – rudnev 2010-02-27 21:34:23

回答

0

Linq確實與此相反。即。如果您把它常態化,你可以很容易地說

from g in grandParents 
from p in g.Parents 
from c in p.Children 
select new { GrandParentName = g.Name, ParentName = p.Name, ChildName = c.Name }; 

做你所要求的是更加棘手。像這樣的東西

var grandparents = (from g in dataSource 
        select new GrandParent { 
         Title = g[0], 
         Parents = (from p in dataSource 
            where p[0] == g[0] 
            select new Parent { 
             Title = p[1], 
             Children = from c in dataSource 
               where p[1] == c[1] 
               select new 
                  { 
                   Title = c[2] 
                  } 
            }).Distinct(new ParentTitleComparer()) 
        }).Distinct(new GrandParentTitleComparer()); 

我不相信這比強制版會更好。

0

這樣做,這將是匿名變量的最基本的方法:

from ds0 in dataSource group ds0 by ds0[0] into grandparents 
select new 
{ 
    Grandparent = grandparents.Key, 
    Parents = 
     from ds1 in grandparents group ds1 by ds1[1] into parents 
     select new 
     { 
      Parent = parents.Key, 
      Children = from ds2 in parents select ds2[2] 
     } 
}; 

如果你想與具體類我建議有一個構造函數的IEnumerable<Person>代表孩子們創造一個Person類來做到這一點Person正在建設中。那麼你可以這樣做:

from ds0 in dataSource 
group ds0 by ds0[0] into grandparents 
select new Person(grandparents.Key, 
    from ds1 in grandparents 
    group ds1 by ds1[1] into parents 
    select new Person(parents.Key, 
     from ds2 in parents 
     select new Person(ds2[2]))); 

這些解決方案中的任何一種都適合你嗎?

如果你想要不同的GrandParentParent & Child類型,那麼你應該能夠修改最後一個例子來適應。

1

您可以使用group by來完成您想要的功能。不幸的是,我對C#LINQ語法的知識是有限的,所以我可以告訴你調用擴展方法GroupBy的方式。

var normalized = dataSource 
    .GroupBy(source => source[0], (grandParent, grandParentChilds) => new { GrandParent = grandParent, Parents = grandParentChilds 
     .GroupBy(source => source[1], (parent, parentChilds) => new { Parent = parent, Children = from source in parentChilds select source[2]}) }); 

foreach (var grandParent in normalized) 
{ 
    Console.WriteLine("GrandParent: {0}", grandParent.GrandParent); 
    foreach (var parent in grandParent.Parents) 
    { 
     Console.WriteLine("\tParent: {0}", parent.Parent); 
     foreach (string child in parent.Children) 
      Console.WriteLine("\t\tChild: {0}", child); 
    } 
}