2012-03-23 90 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