我有一个层次,我想查询有LinqToSql:

国家的">"区域->城市->的邮政编码

每个实体拥有一个参考它的父母(eg.区域。国家)和集合它的儿童(例如。区域。城市).

我想渴望负荷每个实体的父母,沿着与国家和地区,但是懒载城市以及邮政编码。

复杂的事情,每个实体正在本地化之前正在预测模型。这样的国家。名字变更基础上的语言。

这里的一些片段什么我们迄今为止:

public IQueryable<Country> ListCountries()
{
  return ProjectCountry(dataContext.GetTable<ec_Country>());
}

private IQueryable<Country> ProjectCountry(IQueryable<ec_Country> query)
{
  var result = from country in query
  join localized in dataContext.GetTable<ec_CountryLocalization>() on country.CountryID equals localized.CountryID
  let regions = GetRegions(country.CountryID)
  where localized.StatusID == 4 && localized.WebSiteID == this.webSiteID
  select new Country(country.CountryID) {
    CreatedDate = country.CreatedDate,
    IsDeleted = country.IsDeleted,
    IsoCode = country.IsoCode,
    Name = country.Name,
    Regions = new LazyList<Region>(regions),
    Text = localized.Text,
    Title = localized.Title,
    UrlKey = country.UrlKey
  };

  return result;
}

private IQueryable<Region> GetRegions(Int32 countryID)
{
  var query = from r in dataContext.GetTable<ec_Region>()
  where r.CountryID == countryID
  orderby r.Name
  select r;

  return ProjectRegion(query);
}

private IQueryable<Region> ProjectRegion(IQueryable<ec_Region> query)
{
  var result = from region in query
  join localized in dataContext.GetTable<ec_RegionLocalization>() on region.RegionID equals localized.RegionID
  join country in ListCountries() on region.CountryID equals country.CountryID
  let cities = GetCities(region.RegionID)
  select new Region(region.RegionID) {
    Cities = new LazyList<City>(cities),
    Country = country,
    CountryID = region.CountryID,
    CreatedDate = region.CreatedDate,
    IsDeleted = region.IsDeleted,
    IsoCode = region.IsoCode,
    Name = region.Name,
    Text = localized.Text,
    Title = localized.Title,
    UrlKey = region.UrlKey
  };

  return result;
}

...等等。

[TestMethod]
public void DataProvider_Correctly_Projects_Country_Spike()
{
  // Act
  Country country = dataProvider.GetCountry(1);

  // Assert
  Assert.IsNotNull(country);
  Assert.IsFalse(String.IsNullOrEmpty(country.Description));
  Assert.IsTrue(country.Regions.Count > 0);
}

测试失败:

系统。NotSupportedException:方法的系统。皇宫.IQueryable`1[直线。EducationCompass.模型。区域]GetRegions(Int32)'没有支持翻译SQL。

你会如何建议我去?它会更简单的(或可能)如果每个层次是在同一个表而不是独立的吗?

有帮助吗?

解决方案

你会想到使用皇宫设计师设立了关系之间的对象。这让你出编写加入之后加入之后加入通过创建性质。

  • 之间的一个国家及其区域
  • 之间的一个地区,其城市
  • 之间的一个国家及其本地化
  • 区域之间和其本地化

你想要使用 ToList 至独立的这些行动你想要翻译成SQL,这些行动你打算要在地方的代码。如果你不这样做,你就会一直看到的那些"无法翻译方法的成SQL"例外情况。

你还想要使用 DataLoadOptions 急切地载入这些属性,在一些情况。这是我的刺。

DataLoadOptions dlo = new DataLoadOptions();
//bring in the Regions for each Country
dlo.LoadWith<ec_Country>(c => c.Regions);
//bring in the localizations
dlo.AssociateWith<ec_Country>(c => c.Localizations
  .Where(loc => loc.StatusID == 4 && loc.WebSiteID == this.webSiteID)
);
dlo.AssociateWith<ec_Region>(r => r.Localizations);

//set up the dataloadoptions to eagerly load the above.
dataContext.DataLoadOptions = dlo;

//Pull countries and all eagerly loaded data into memory.
List<ec_Country> queryResult = query.ToList();

//further map these data types to business types
List<Country> result = queryResult
  .Select(c => ToCountry(c))
  .ToList();

public Country ToCountry(ec_Country c)
{
  return new Country()
  {
    Name = c.Name,
    Text = c.Localizations.Single().Text,
    Regions = c.Regions().Select(r => ToRegion(r)).ToList()
  }
}

public Region ToRegion(ec_Region r)
{
  return new Region()
  {
    Name = r.Name,
    Text = r.Localizations.Single().Text,
    Cities = r.Cities.Select(city => ToCity(city)).ToLazyList();
  }
}

其他提示

这是一个粘性一段代码,而我不会回答这个因缺乏相关技术人员,如果任何人有,但因为你没有反应......

我可以告诉你的错误消息意味着什么。这意味着该功能GetRegions无法通过的LINQ to SQL供应商转换成SQL。一些内置的功能就可以了,因为供应商理解他们,这里是一个列表。否则,你可以提供翻译请参见这里

在你的情况,你需要“内联”此查询的逻辑,逻辑不跨越函数调用的边界,因为你正在处理一个表达式树时,SQL Server不能回调到您的GetRegions方法。

至于这样做的具体的方式,你必须有一个去,我没有答应你此刻的时间。 (除非有其他人的时间和技能?)

好运。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top