2010-04-20 25 views
0

我有幾個表,其中有一對多的關係。假設我有一個國家表格,一個FK到國家的州表格和一個FK到州表格的城市表格。LINQ到Entites:做一對多關係計數

我希望能夠創造出所有城市的數量對於給定的國家,也是基於過濾城市的數 - 是這樣的:

foreach(var country in Model.Country) { 
    total = country.State.All().City.All().Count() ; 
    filtered = country.State.All().City.Any(c=>c.field == value).Count(); 
} 

顯然,這不工作 - 有沒有辦法做到這一點?

更新:

我可以遍歷直通對象:

foreach (var item in Model) { 

     ... other stuff in here ... 

     int tot = 0; 
     int filtered = 0; 
     foreach (var state in item.State) 
     { 
     foreach (var city in state.City) 
     { 
      tot++; 
      if (city.Field == somevalue) 
      filtered ++; 
     } 
     } 

     ... other stuff in here ... 

    } 

,但似乎並不很優雅。

更新:@AD有幾個建議,但什麼工作要解決的問題是:

int tot = item.States.Sum(s=>s.City.Count); 
int filtered = item.States.Sum(s=>s.City.Where(c=>c.Field == somevalue).Count()); 

回答

1

你可以試一下,假設你已經擁有了givenCountry和填充值變量:

int total = EntityModel.CitySet.Where(it => it.State.Country.ID == givenCountry.ID).Count(); 

上面,你把你的整個組城市(EntityMode.CitySet)。這個集合包含所有國家所有州的所有城市。問題就變成了:這些城市的哪個子集在'countryCountry'的國家?要弄明白,你將Where()應用於整個集合,並且比較國家id以查看它們是否相同。然而,由於這個城市只知道它處於哪個國家(而不是國家),所以你首先必須引用它的狀態(it.State)。它引用狀態對象,並且該對象具有將引用該國家的國家/地區屬性。然後它。國家。國家引用國家「它」在和「它」是城市,在城市和國家之間建立聯繫。

注意,你可以這樣做是

int total = givenCountry.Sum(c => c.States.Sum(s.Cities.Count())) 

但是反轉爲好,在這裏你將不得不確保givenCountry有其國集加載到內存中,也即每個國家都有其城市收集加載。這是因爲您在加載的對象上使用Linq-to-Entities,而不是在第一個示例中的Entity Framework實例對象上。有一種方法,以工藝的最後一個查詢使用,但是實體框架對象:

int total = EntityModel.CountrySet.Where(c => c.ID == givenCountry.ID).Sum(c => c.States.Sum(s.Cities.Count())) 

至於城市與特定字段中的數字,你採取了類似的方法用在哪裏()調用:

int filtered = EntityModel.CitySet.Where(it => it.field == value).Count(); 
+0

問題是linq到實體不能這樣工作。我的模型是一個國家集合,一個國家沒有城市財產 - 它有一個國家集合,並且每個州都有一個城市集合。 – chris 2010-04-20 13:04:58

+0

如果一個國家擁有一個國家集合,然後相互對立,那麼該國就有一個它所隸屬的國家。各州和城市也是如此。所以,這意味着從一個城市,你可以到達國家,然後到達國家。當然,這是假設您正在使用實體框架,並且您正在使用實體關係(從數據庫中的外鍵或從模型查看器手動構建)。如果您手動或從其他模型提供者構建了國家/州/城市對象,則該關係將取決於您需要向我們提供的那些模型。 – ADB 2010-04-20 13:35:24

+0

使用EF和asp.net MVC 1.0。模型包含IEnemurable ,並且有關係。解決方案的問題在於國家沒有城市導航屬性 - 只是國家的集合。 – chris 2010-04-20 13:52:35

0

你必須在實體框架明確加載孩子。如果你加載所有的孩子,那麼你可以得到很好的計數。

IEnumberable<Country> countries = Model.Country.Include("State"); 
total = countries[i].State.Count(); 

當然假設通過所有國家的迭代是重要的。否則,爲什麼不只是針對由州和國家過濾的城市進行查詢?

在你的國家的foreach你應該能夠做到

tot += state.City.Where(x=> x.Field == value).Count(); 
+0

我的模型加載了所有對象 - 我正在遍歷它們並顯示詳細信息,但我想要一些統計信息(「4/7城市..」)類型的東西。 – chris 2010-04-20 12:50:44

+0

如果它完全加載,只是嵌套你的循環,迭代通過每個狀態,而不是做state.All() – 2010-04-20 12:52:20

+0

我剛更新我的問題,以顯示如何迭代工作。雖然這看起來相當不雅。 – chris 2010-04-20 13:12:54

0

你爲什麼不扭轉這種局面?

foreach(var country in Model.Country) { 
    var city = Model.State.Where(x=>x.StateID==country.State.StateID).Select(x=>City) 
    total = city.Count(); 
    filtered = city.All(c=>c.field == value).Count(); 
}