42

그래서 내 EF 모델은 관계가 있고 예제에서 보았 듯이 이러한 관계는 ICollection의 가상 속성으로 수행되어야합니다.EF ICollection 대 ​​목록 비교 IEnumerable 대 IQueryable

예 : 나는 지연된 실행을 방지하기는 IEnumerable을 사용해야 선가

public class Task 
    { 
     public int Id { get; set; } 
     public string Description { get; set; } 
     public virtual ICollection<SubTask> { get; set; } 
    } 

, 맞습니까? 즉, 내 DAL 메서드가 IQueryable의 IEnumerable을 반환하면 SQL이 그 순간에 실행되고 웹 페이지에서 .TOList를 호출하는 순간이 아니라는 것을 의미합니다.

그래서 가장 좋은 방법은 무엇입니까? 나는 무엇을 돌려 보내야 하는가? IEnumerable, List?, IList, ICollection?

들으

+0

'가상'실행 연기에 대한 책임이 있다고 생각하지만 틀렸을 수도 있습니다. – mfussenegger

+0

@mfussenegger 가상은 덮어 쓸 수있는 선언에 사용됩니다. –

답변

60

IQueryable : 당신이 정말 어쩌면 .ToList() 또는 foreach을 수행하여 항목을 반복 할 때까지

  • 쿼리가 실행되지 않습니다. 즉, Where()과 같은 필터를 추가 할 수 있습니다.
  • 는 IEnumerable을

IEnumerable 클래스 : 항목의

  • 앞으로 전용 목록입니다. 항목 0-3을 전달하지 않고 "항목 4"에 도달 할 수 없습니다.
  • 읽기 전용 목록으로 추가하거나 제거 할 수 없습니다.
  • 여전히 지연된 실행을 사용할 수 있습니다 (IQueryable은 여전히 ​​IEnumerable 임).

IList :

  • 전체 목록에 랜덤 액세스
  • 아마 완전히 메모리 (? 정확한 클래스가이를 구현 무엇을 알고,하지만 지연된 실행)에
  • 이 추가 지원 제거 및 제거
  • 확장 IEnumerable 및 ICollection

ICollection :

  • IEnumerable과 IList 사이에 있습니다.
  • 무엇

는 "가장"사용자의 요구 사항에 따라 IEnumerable을 확장합니다. 일반적으로 항목을 표시하려는 경우 IEnumerable은 "충분 함"이지만 적어도 항상 제네릭 변형을 사용하십시오.

+3

탐색 속성을 IEnumerable 으로 표시하면 항목을 컬렉션에 추가 할 수 없습니다. –

+4

좋은 분해하십시오. 추측 된 실행에 대해서는 IEnumerable (다른 형식이 모두 파생 됨)에서 .GetEnumerator를 호출 할 때까지 쿼리가 형성되지 않습니다. IQueryable이 아닌 다른 것을 사용하면 모든 결과가 클라이언트에 전달되어 데이터베이스 수준에서 필터가 적용되는 대신 필터링됩니다. GetEnumerator가 적절한 TSQL을 생성하는 데 사용할 표현식 트리를 유지하려면 IQueryable이 필요합니다. –

+1

또한 http://stackoverflow.com/a/10113331/870291을 참조하십시오. – dotNETbeginner

1

EF의 또 다른 차이점은 실제로 목록을 열거 할 때까지 IEnumerable이 DB에 대한 쿼리를 실행하지 않는다는 것입니다. IList가 쿼리를 실행하고 메모리의 항목을 가져 오는 동안. 나는 캐싱에 이상한 행동을했다. IEnumarable을 Chaching하는 것은 항목을 저장하지 않고 대신에 호출을 호출하고 일부 목적을 위해 열거 형을 가져올 때마다 DB로 이동하여 쿼리를 실행하므로 캐싱은 쓸모가 없습니다.그러나 ToList()는 항목을 가져 와서 항목을 캐시에 저장 했으므로이 경우 DB를 한 번만 방문하십시오. 이 게시물에서 더 찾기 : http://www.dailycode.info/BlogV2/post/entityframework-adding-ienumerable-to-cache