2014-04-25 3 views
2

저는 EF6을 사용하고 있으며 동적로드를 사용하여 지연로드 및 변경 내용 추적을 지원합니다. 어쨌든 열거 자 또는 count 속성이 먼저 호출 될 때 데이터를로드하는 대신 속성에 액세스하면 지연로드가 트리거됩니다. 그래서 나는 프록시를 죽일 수 있고 사용자 정의 프록시로 대체하려고했습니다. 사용자 정의 개체 컨텍스트를 사용하고 CreateObject 메서드를 오버로드하는 것은 쉬운 일이었습니다. 불행히도 ObjectMaterialized 이벤트는 엔티티를 대체 할 수 없으며 쿼리의 엔티티를 바꿀 수 없습니다. 객체의 생성은 프레임 워크의 내부 클래스에 깊이 위치합니다.엔티티 프레임 워크 : POCO의 사용자 지정 프록시

사용자 정의 프록시를 사용하는 방법에 대한 아이디어가 있습니까? 또는 개체 쿼리에서 구체화 된 엔터티를 어떻게 대체 할 수 있습니까?

답변

1

N+1 query problem을 피하기 위해 가져올 속성을 .Include으로 설정해야합니다.

public class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set ;} 

    public virtual ICollection<Post> Posts { get; set; } 
    public virtual ICollection<Comment> Comments { get; set; } 
} 

public class Post 
{ 
    public int Id { get; set; } 
    public string Title { get; set ; } 

    public int AuthorId { get; set; } 
    public virtual User Author { get; set; } 

    public virtual ICollection<Comment> Comments { get; set; } 
} 

public class Comment 
{ 
    public int Id { get; set; } 
    public string Note { get; set ;} 

    public int PostId { get; set; } 
    public virtual Post Post { get; set; } 

    public int AuthorId { get; set; } 
    public virtual User Author { get; set; } 
} 

public class BlogContext : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Post> Posts { get; set; } 
    public DbSet<Comment> Comments { get; set; } 
} 

다음이는 쿼리의 톤 할 것이라는 점에서 BAD입니다 :

using (var db = new BlogContext()) 
{ 
    var user = db.Users.Single(u => u.Id=5)); // +1 query 
    foreach (var post in user.Posts) // N queries 
    { 
     var message = String.Format("{0} wrote {1}", user.Name, post.Title); 
     Console.WriteLine(message); 

     foreach (var comment in post.Comments) // N * M queries! 
     { 
      // and that .Author make N * M MORE! 
      var message = String.Format("\t{0} commented {1}", comment.Author.Name, comment.Note); 
      Console.WriteLine(message); 
     } 
    } 
} 

을 그리고 그것은 쿼리 할 수 ​​있습니다 점에서이 좋은입니다 :

using (var db = new BlogContext()) 
{ 
    var user = db.Users 
       .Single(u => u.Id=5)) 
       .Include(u => u.Posts) // eliminates the N post queries 
       .Include(u => u.Posts.Comments) // eliminates the M comment queries 
       .Include(u => u.Posts.Comments.Author); // eliminates the M comment author queries 

    foreach (var post in user.Posts) // N queries 
    { 
     var message = String.Format("{0} wrote {1}", user.Name, post.Title); 
     Console.WriteLine(message); 

     foreach (var comment in post.Comments) // N * M queries! 
     { 
      // and that .Author make N * M MORE! 
      var message = String.Format("\t{0} commented {1}", comment.Author.Name, comment.Note); 
      Console.WriteLine(message); 
     } 
    } 
} 
관련 문제