문제

LinQTOSQL로 쿼리하고 싶은 계층 구조가 있습니다.

국가 -> 지역 -> 도시 -> zipcode

각 엔티티는 부모 (예 : Region.country)와 IT의 어린이 모음 (예 : 지역)에 대한 참조를 보유하고 있습니다.

나는 각 단체의 부모를 국가 및 지역과 함께로드하고 있지만 게으른 부하 도시 및 우편 번호를 열망하고 싶습니다.

물건을 복잡하게하기 위해 각 엔티티는 모델에 투사되기 전에 현지화되고 있습니다. 따라서 언어를 기준으로 이름이 변경됩니다.

지금까지 내가 가진 것들이 있습니다.

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);
}

테스트는 다음과 같이 실패합니다.

System.NotSupportedException : Method 'System.linq.iqueryable`1 [Beeline.educationcompass.model.region] getRegions (int32)'에는 SQL에 대한 번역이 없습니다.

내가 이것에 대해 어떻게 추천 하시겠습니까? 계층 구조의 각 레벨이 별도의 계층 대신 동일한 테이블에있는 경우 더 간단할까요 (또는 가능)?

도움이 되었습니까?

해결책

LINQ 디자이너를 사용하여 객체 간의 관계를 설정하고 싶을 것입니다. 이를 통해 속성을 작성하여 가입 후 조인 후 조인이됩니다.

  • 국가와 지역 사이
  • 지역과 도시 사이
  • 국가와 지역화 사이
  • 지역과 지역화 사이

당신은 사용하고 싶을 것입니다 톨리스트 해당 작업을 분리하려면 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();
  }
}

다른 팁

그것은 하나의 끈적 끈적한 코드이며, 다른 사람이 있었다면 관련 기술이 부족하여 이것에 대답하지 않았을 것입니다. 그러나 당신은 응답이 없었기 때문에 ...

오류 메시지가 무엇을 의미하는지 말할 수 있습니다. 이는 LINQ에서 SQL 공급자에 의해 기능 get 영역을 SQL로 변환 할 수 없음을 의미합니다. 제공자가 이해하기 때문에 일부 내장 기능은 다음과 같습니다. 목록. 그렇지 않으면 번역을 참조 할 수 있습니다 여기.

당신의 상황에서 당신은이 쿼리의 논리를 '인라인'해야한다면, 논리는 표현식 트리를 다루기 때문에 SQL 서버는 getRegions 메소드로 다시 호출 할 수 없기 때문에 함수 호출의 경계를 가로 지르지 않습니다.

그렇게하는 정확한 방법에 관해서는, 당신은 가야 할 것입니다. 나는 지금 당신을 의무화 할 시간이 없습니다. (다른 사람이 시간과 기술이 없다면?)

행운을 빕니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top