가상 키워드가 Entity Framework 4.1 POCO 코드에서 어떤 영향을 미칠 수 있습니까?


229

virtual키워드가 EF 코드 우선의 속성에 사용될 때 영향을 미칩니 까 ?. 다른 상황에서 모든 파급 효과를 설명 할 수 있습니까?

예를 들어 지연로드를 제어 할 수 있다는 것을 알고 있습니다 . ICollection / 일대 다 관계 속성에서 가상 키워드를 사용하면 기본적으로 지연로드되지만 가상 키워드는 그대로두면됩니다. 열심이다

virtualPOCO 엔터티와 함께 ​​EF에서 키워드가 가질 수있는 다른 효과는 무엇입니까 ? 기본적 virtual으로 모든 속성 을 사용하도록 설정해야합니까 , 아니면 기본 속성 을 사용 하지 않아야합니까?

답변:


194

지금까지 이러한 효과에 대해 알고 있습니다.

  • 지연로드 : virtual특별히 표시하지 않는 한 모든 ICollection은 지연로드됩니다.
  • 보다 효율적인 변경 추적 . 다음 요구 사항을 모두 충족하면 변경 내용 추적에 가상 속성을 연결하여보다 효율적인 방법을 사용할 수 있습니다. 링크에서 :

    변경 내용 추적 프록시를 얻으려면 기본 규칙은 클래스가 공개, 비추 상 또는 비밀 봉 상태 여야한다는 것입니다. 또한 클래스는 유지되는 모든 속성에 대해 퍼블릭 가상 게터 / 세터를 구현해야합니다. 마지막으로 컬렉션 기반 관계 탐색 속성 ICollection<T>만 선언해야합니다 . 구체적인 구현 또는 파생 된 다른 인터페이스 일 수 없습니다 ICollection<T>(지연된로드 프록시와의 차이).

이를 설명하는 또 다른 유용한 링크는 POCO 프록시 생성을위한 MSDN의 요구 사항입니다 .


52
속성을 가상으로 만드는 다른 이유는 없습니다. 탐색 특성은 지연로드의 경우 가상으로 표시되고 스칼라 특성은 변경 추적의 경우 가상으로 표시됩니다.
Ladislav Mrnka

10
탐색 속성은 무엇이며 스칼라 속성은 무엇입니까?
Abid Ali

9
@ AbidAli : 탐색 속성은 외래 키 (엔터티 클래스 유형) 또는 일대 다 관계 (ICollection <> 유형)라고 생각합니다. 스칼라 속성은 기본 형식 (int, string, ..) 또는 ComplexType (기본 형식의 구조체)입니다.
Scott Stafford

2
" public virtual byte[] bigData { get; set; }"게으른 로딩입니까?
AechoLiu

9
bytes []는 간절히로드되며 외래 키만 지연 될 수 있습니다. 해당 열을 가져 오지 않으려면 전체 레코드를 가져 오지 마십시오 .Select(a=>new { fields you want }).
Scott Stafford

63

이 가상 키워드는 엔티티 프레임 워크에서 데이터를로드하는 주제 (지연 한로드, 열성적인로드 및 명시 적로드)와 관련이 있습니다.

지연 로딩으로 데이터를로드 하려면 virtual 키워드를 사용해야합니다 .

지연로드 는 엔티티 또는 엔티티 콜렉션이 처음 액세스 될 때 데이터베이스에서 자동으로로드되는 프로세스입니다.

예를 들어, 아래에 정의 된 블로그 엔티티 클래스를 사용하는 경우 게시물 탐색 특성에 처음 액세스 할 때 관련 게시물이로드됩니다.

public class Blog 
{  
     public int BlogId { get; set; }  
     public string Name { get; set; }  
     public string Url { get; set; }  
     public string Tags { get; set; }  
     public virtual ICollection<Post> Posts { get; set; }  
}

Posts 속성을 비가 상으로 설정하여 Posts 컬렉션의 지연로드를 해제 할 수 있습니다.

지연로드가 해제 된 경우에도 간결한로드 (포함 메소드 사용) 또는 관련 엔티티 명시 적로드 (로드 메소드 사용)를 사용하여 게시물 콜렉션로드를 계속 수행 할 수 있습니다.

열심히로드 :

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
                          .Include(b => b.Posts) 
                          .ToList(); 
}

명시 적으로로드 중 :

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
}

1
가상 (lazy-loading)을 사용할 때 N + 1 문제를 피하는 방법은 무엇입니까? 예를 들어, context.Blogs.ToList (); 그런 다음 테이블을 조인하지 않고 블로그 수만큼 선택 쿼리를 실행합니다.
전문가가

1
@Expertwannabe 지연 로딩을 사용하더라도을 호출하여 명시 적으로 열망로드를 요청할 수 있습니다 Include().
Monsignor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.