주소 클래스에는 이미 관계를 나타내는 State 속성이 있습니다. 왜 그냥 사용하지 않니?
public IQueryable<string> Addresses()
{
var query = from a in _contextProvider.Context.Addresses
where a.CityName.StartsWith("I")
select a.State.StateName;
return query;
}
업데이트 : 최신 코멘트에서
내가 false로 LazyLoadingEnabled
을 설정하여 모델에 대한 게으른 로딩을 해제 같아요. 기본적으로 lazy loading이 가능합니다. 이전 버전의 EF는 lazy loading을 지원하지 않았기 때문에 다소 혼란 스러울 수 있습니다.
지연로드를 비활성화하면 명시 적로드가 "활성화"되고 관련 개체를 명시 적으로로드해야합니다.
var query = from a in _contextProvider.Context.Addresses.Include("State")
where a.CityName.StartsWith("I")
select a;
또는 (최종 쿼리를 수정) 쿼리에 관련된 속성에 액세스 : 귀하의 경우에 당신은 (이것은 열망로드라고합니다)를 Include
방법을 사용하여이 작업을 수행 할 수 있습니다
var states = (from a in Addresses() // Addresses is your query method
select a.State).ToList();
을 두 번째 버전에서는 linq-to-entities가 쿼리에서 액세스하기 때문에 상태가 자동으로 포함됩니다. Addresses
메서드는 IQueryable
을 반환하므로 실제로 열거되기 전에 쿼리가 실행되지 않습니다. 따라서 실행 된 SQL 쿼리는 Addresses
이 반환 한 쿼리를 사용하는 방법에 따라 달라집니다. 먼저 Addresses
쿼리를 실행하고 나중에 상태를 액세스하는 경우
LINQ - 투 - 엔티티를 포함하지 않습니다
var states = (from a in Addresses().ToList() // <- ToList() executes the query before states are accessed
select a.State).ToList();
게으른 로딩은 종종 데이터베이스에 불필요한 왕복을 방지하기 위해 꺼집니다. 지연로드를 활성화 한 다음 Addresses
에 의해 반환 된 쿼리를 즉시 실행하면 관련 객체에 대한 각각의 액세스가 실제로 데이터베이스 쿼리를 생성합니다. 그러나 다시 : 최종 질의에 상태를 포함하면 linq-to-entities는 자동으로 JOIN을 생성하여 (지연로드를 사용하는지 여부와 관계없이)이를 포함시킵니다.
Include
을 사용하여 관련 상태를 열심히로드하는 솔루션은 나중에 액세스하지 않아도 괜찮습니다. 그리고 조인을 사용하는 원래 생각도 괜찮습니다. 그러나 당신의 방법이 IQueryable<Address>
을 돌려주기를 원하기 때문에, 당신은 콜 사이트에서 그것을해야만합니다.
게으른 로딩을 활성화 한 경험으로 인해 작업이 훨씬 수월해졌습니다.진행 상황을 정확히 모르는 경우 데이터베이스로의 불필요한 왕복이 발생할 수 있습니다. 그러나 여전히 Include
을 사용하여 쿼리를 최적화 할 수 있습니다. 더 나은 LINQ 쿼리가 나는 SQL 프로파일 (또는 Express Profiler 같은 무료 도구 당신이 사용하는 경우 SQL Server Express를) 사용하는 것이 좋습니다 SQL 문으로 변환되는 방법을 이해합니다. 또한 통증이있을 수있는 명시 적 로딩을 사용하는 반면에
. 관련 테이블을 모두 포함 시키면 huge datasets이됩니다. 어떤 이유로 당신이 모든 관련 테이블을 포함 할 수없는 경우 당신은 개체가로드되는 경우 명시 적으로 확인해야 : context.Entry(address).Reference(a => a.State).IsLoaded
은. Nullable 속성이 null 인 경우 데이터베이스에서 NULL인지 또는 아직로드되지 않았는지 알 수 없습니다.
이렇게하면 변환 오류가 발생합니다 (암시 적으로 'System.Linq.IQueryable'형식으로 'System.Linq.IQueryable '형식으로 변환 할 수 없음). 이유를 이해합니다. 상태 이름뿐 아니라 모든 주소 필드를 원합니다. 명시 적으로 나열해야합니까? 그런 다음 그것을 던져야합니까? 감사합니다 –
mwill
@mwill : 나는'된 IQueryable'에 반환 형식을 변경했습니다. 모든 주소 필드를 가져 오려면 코드가 완벽하게 괜찮습니다. JOIN은 State 속성의 ForeignKey 특성을 통해 이미 수행됩니다. –
pescolino
예, 모든 주소 입력란을 원합니다. 내 원래 코드에서 State는 NULL이므로 직접 join을 작성해야한다고 생각했습니다. 어딘가에 놓친 것 같은데? 덕분에 – mwill