我怎么可以查询的层次结构与LinqToSQL?
-
19-08-2019 - |
题
我有一个层次,我想查询有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();
}
}
不隶属于 StackOverflow