2

나는 내 머리 속에서이 머리글을 긁어 왔지만 여전히 그 원인을 파악하지 못했습니다.리포지토리 패턴을 사용하는 SQL에 Linq : 개체가 SQL에 대한 번역을 지원하지 않습니다

두 개의 다른 리포지토리를 참조하는 복합 리포지토리 개체가 있습니다. LINQ 쿼리에서 Model 유형을 인스턴스화하려고합니다 (첫 번째 코드 스 니펫 참조).

public class SqlCommunityRepository : ICommunityRepository {

private WebDataContext _ctx; 
    private IMarketRepository _marketRepository; 
    private IStateRepository _stateRepository; 

    public SqlCommunityRepository(WebDataContext ctx, IStateRepository stateRepository, IMarketRepository marketRepository) 
    { 
     _ctx = ctx; 
     _stateRepository = stateRepository; 
     _marketRepository = marketRepository; 
    } 

    public IQueryable<Model.Community> Communities 
    { 
     get 
     { 
      return (from comm in _ctx.Communities 
        select new Model.Community 
        { 
         CommunityId = comm.CommunityId, 
         CommunityName = comm.CommunityName, 
         City = comm.City, 
         PostalCode = comm.PostalCode, 
         Market = _marketRepository.GetMarket(comm.MarketId), 
         State = _stateRepository.GetState(comm.State) 
        } 
        ); 
     } 
    } 
} 

내가 좋아하는 모습을 전달하고있어 리포지토리 개체이

public class SqlStateRepository : IStateRepository {

private WebDataContext _ctx;

public SqlStateRepository(WebDataContext ctx) { _ctx = ctx; }

public IQueryable<Model.State> States 
    { 
     get 
     { 
      return from state in _ctx.States 
        select new Model.State() 
        { 
         StateId = state.StateId, 
         StateName = state.StateName 
        }; 
     } 
    } 

    public Model.State GetState(string stateName) 
    { 
     var s = (from state in States 
       where state.StateName.ToLower() == stateName 
       select state).FirstOrDefault(); 

     return new Model.State() 
     { 
      StateId = s.StateId, 
      StateName = s.StateName 
     }; 
    } 

public class SqlMarketRepository : IMarketRepository {

private WebDataContext _ctx;

public SqlMarketRepository(WebDataContext ctx) 
    { 
     _ctx = ctx; 
    } 

    public IQueryable<Model.Market> Markets 
    { 
     get 
     { 
      return from market in _ctx.Markets 
        select new Model.Market() 
           { 
            MarketId = market.MarketId, 
            MarketName = market.MarketName, 
            StateId = market.StateId 
           }; 
     } 
    } 

    public Model.Market GetMarket(int marketId) 
    { 
     return (from market in Markets 
       where market.MarketId == marketId 
       select market).FirstOrDefault(); 
    } 
} 

내가 모든 걸 배선있어 방법이있다 :

 WebDataContext ctx = new WebDataContext(); 
     IMarketRepository mr = new SqlMarketRepository(ctx); 
     IStateRepository sr = new SqlStateRepository(ctx); 
     ICommunityRepository cr = new SqlCommunityRepository(ctx, sr, mr); 
     int commCount = cr.Communities.Count(); 

위 스 니펫의 마지막 줄은 실패한 부분입니다. 인스턴스화 (new Model.Community)를 통해 디버깅 할 때 다른 저장소 메소드 중 하나로 들어 가지 않습니다. 이 세 가지 객체 뒤에있는 기본 테이블 간에는 관계가 없습니다. 이것은 LINQ to SQL이 표현식 트리를 올바르게 구축 할 수없는 이유입니까? 다음과 같습니다 다른 저장소 방법을 추가

답변

1

완전 수화물이 아닌 수화되지 않은 쿼리입니다.

커뮤니티 쿼리는 이 개체가 수화됨에 따라 메서드를 호출하기 때문에 다른 두 쿼리와 다릅니다. 이 메소드 호출은 SQL로 변환 할 수 없습니다.


일반적으로 이것은 문제가되지 않습니다. 예를 들어 Communities.ToList()라고 말하면 작동하고 메소드는 수화됨에 따라 객체에서 호출됩니다.

개체가 수화되지 않은과 같은 쿼리를 수정 한 경우 Communities.Count()라고 말하면 linq to sql은 메서드 호출을 데이터베이스에 보내고 시도 할 수 없으므로 throw합니다. 이러한 메서드 호출이 궁극적으로 결과 개수에 영향을 미치지 않더라도이 작업을 수행합니다.


간단한 수정 (당신이 진정으로 완전히 수화 컬렉션을 기대하는 경우)를 보습, 커뮤니티 쿼리에 ToList를 추가하는 것입니다.

+0

그랬습니다. IQueryable에서 메서드를 호출 할 때까지 쿼리가 실행되지 않습니다? – Praveen

+1

대부분의 Linq 메서드는 지연되어 결과가 열거 될 때까지 쿼리를 평가하지 않습니다. foreach와 ToList는 둘 다 쿼리를 열거하는 수단입니다. –

0

시도 :

public int CommunitiesCount() 
{ 
    get { return _ctx.Communities.Count(); } 
} 

이 당신은 내가 당신이하려는 생각이다 사용자에게 전체 오브젝트 트리를 노출하지 않고 카운트를 반환 할 수 있습니다 어쨌든.

이미 짐작할 수 있겠지만, 익명 형식이라고하는 것은 잘못되었습니다 (실제로 익명 형식이 아니라 실제 개체이며 일부는 숨기려는 것으로 보이지만) 최종 사용자의 필드 중 하나).

+0

Count() 메서드 자체가 범인인지 확실하지 않습니다. 커뮤니티를 할 때, 전 수화 된 IQueryable 컬렉션을 기대하고 있습니다. mr.Markets.Count() 및 sr.States.Count()는 예상 된 결과를 반환합니다. – Praveen

+0

count()의 특정 변환이 작동 했습니까? –

+0

예, _ctx.Communities.Count()가 올바른 카운트를 제공합니다. 그러나 IQueryable 목록 인 communityRepository.Communities를 찾고 있습니다. – Praveen

관련 문제