2012-03-23 99 views
0

在多語言數據庫中,我有以下表格:實體框架 - 複雜的查詢最佳實踐

  • 區& AreaLocale:區域包含緯度/經度/ areaID表示& AreaLocale包含ID /名稱/說明/ areaID表示/ CultureId
  • 國家& CountryLocale:國家包含緯度/經度/ CountryId & CountryLocale包含ID /名稱/說明/ CountryId/CultureId
  • 文化:包含ID /名稱/顯示名稱

現在,我需要的是找回如下:

areaID表示/名稱/說明/經度/緯度/ CountryId /國家名稱/ CultureId /文化顯示名稱,如該區域的請將isDeleted =假。

下面的查詢寫的是:

var q = (from areas in context.Areas 
join countries in context.Countries on areas.CountryId equals countries.CountryId 
join arealocales in context.AreaLocales on areas.AreaId equals arealocales.AreaId 
join cultures in context.Cultures on arealocales.CultureId equals cultures.CultureId 
join countrylocales in context.CountryLocales on areas.CountryId equals countrylocales.CountryId 
where areas.IsDeleted == false 
select new Area() 
{ 
     CountryId = areas.CountryId, 
     CountryName = countrylocales.Name, 
     CultureId = cultures.CultureId, 
     CultureDisplayName = cultures.DisplayName, 
          Description = arealocales.Description, 
     Id = areas.AreaId, 
     Latitude = areas.Latitude, 
     Longitude = areas.Longitude, 
     Name = arealocales.Name 
}).ToList(); 

是否有書面上面的查詢,而不是使用聯接和使用UnionAll而不是一個更好的辦法?

+0

您是否在模型中有導航屬性,例如'public ICollection AreaLocales {get;組; }'和'公共國家國家{get;組; ''在'Area'類中,等等?如果你有這些,你根本不需要任何手寫連接。 – Slauma 2012-03-24 23:40:37

+0

事實上,我有以下內容:區域AreaLocales,區域實體Country country和國家CountryLocale List。如何實現與上述相同的目標?謝謝 – Bill 2012-03-24 23:54:40

回答

1

關於你的評論:

其實,我有以下幾點:在區AreaLocales,國家對區域實體 財產清單,並在國家CountryLocale的名單。

我也假設AreaLocaleCulture屬性(因爲你顯然對AreaLocaleCultureId屬性):

var q = (from area in context.Areas 
     where area.IsDeleted == false 
     select new // or: select new SomeHelperClass 
     { 
      Id = area.AreaId, 
      Latitude = area.Latitude, 
      Longitude = area.Longitude, 
      CountryId = area.CountryId, 

      AreaLocales = area.AreaLocales.Select(areaLocale => new 
      { 
       Description = areaLocale.Description, 
       Name = areaLocale.Name, 
       CultureId = areaLocale.Culture.CultureId, 
       CultureDisplayName = areaLocale.Culture.DisplayName 
      }), 

      CountryNames = area.Country.Countrylocales.Select(
       countryLocale => countryLocale.Name) 
     }) 
     .ToList(); 

結果對象有兩個嵌套表四個AreaLocales和CountryNames。如果這些類的幾乎所有特性,反正你也可以只使用預先加載:

var q = (from area in context.Areas 
      .Include(a => a.AreaLocales.Select(al => al.Culture)) 
      .Include(a => a.Country.CountryLocales) 
     where area.IsDeleted == false 
     select area) 
     .ToList(); 

實體框架將創建當這些LINQ查詢翻譯成SQL必要的連接。

+0

感謝您的印象深刻的答案。我想了解上面的細節。上面的查詢將返回每個區域的Area列+ AreaLocale集合。至於CountryNames,每個區域都有一個國家,所以我認爲CountryNames會包含一個國家的所有區域,這個區域與Area相連,對不對? 瞭解EF的任何優秀資源,如何針對它進行查詢?謝謝 – Bill 2012-03-25 09:33:53

+0

還有一個問題,如果我想過濾掉基於Country&Culture的數據,我會添加一個.Where()到AreaLocales&另一個到CountryNames? – Bill 2012-03-25 09:34:44

+0

@bhaidar:是的,您在第一條評論中的理解是正確的。是的,您可以在第一個示例中添加一個「Where」來過濾子對象,但不會在第二個示例中(「Include」中)因爲預加載不允許過濾所包含的屬性。 EF 4.1的好介紹在這裏:http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-1-introduction-and- model.aspx – Slauma 2012-03-25 11:53:18