2013-05-03 15 views
5

Tôi đang sử dụng Mô hình EF đầu tiên với các thực thể POCO và với DbContexts tùy chỉnh. Vấn đề của tôi là thiết lập LazyLoadingEnabled=false không ảnh hưởng đến bất cứ điều gì, các thuộc tính điều hướng vẫn được tải. Dưới đây là ví dụ của tôi được đơn giản hóa.Cài đặt LazyLoadingEnabled dường như không hoạt động trong EF 5

Chương trình thực thể. Một chương trình có thể tham gia các chương trình khác:

namespace Domain.Entities 
{ 
    using System; 
    using System.Collections.Generic; 

    public partial class Program 
    { 
     public Program() 
     { 
      this.Programs = new HashSet<Program>(); 
     } 

     public int Id { get; set; } 
     public string Title { get; set; } 
     public string Description { get; set; } 
     public System.DateTime StartDate { get; set; } 
     public System.DateTime EndDate { get; set; } 
     public Nullable<int> ProgramId { get; set; } 

     public virtual ICollection<Program> Programs { get; set; } 
     public virtual Program OwnerProgram { get; set; } 
    } 
} 

Các DbContext:

namespace Infrastructure.Model 
{ 
    public class ProgramContext : DbContext 
    { 
     public ProgramContext() 
      : base("name=MyContainer") 
     { 
      Configuration.LazyLoadingEnabled = false; 
     } 

     public DbSet<Program> Programs { get; set; } 
    } 
} 

Sau đây là cách tôi sử dụng nó:

private ProgramContext _dbContext = new ProgramContext(); 

// GET api/program 
public IEnumerable<Program> GetPrograms() 
{ 
    List<Program> list = _dbContext.Programs.ToList(); 
    return list; 
} 

Với ví dụ trên, EF vẫn tải các chương trình và thuộc tính OwnerProgram của lớp Program. Tôi đã thử xóa các từ khóa ảo, vô hiệu hóa việc tạo proxy và cũng đã xác minh rằng LazyLoadingEnabled=false trên chính Mô hình.

Tôi có thiếu gì đó không?

Trả lời

6

Hiệu ứng bạn đang thấy được gọi là sửa lỗi mối quan hệ.

Thực tế thuộc tính điều hướng là không phải được tải một cách rõ ràng. Truy vấn _dbContext.Programs.ToList() chỉ tải toàn bộ bảng Programs từ cơ sở dữ liệu.Đây chỉ là một truy vấn SQL đơn giản (như SELECT * FROM ProgramsTable) mà không có bất kỳ mệnh đề WHERE và không có bất kỳ JOIN nào cho các hàng có liên quan.

Ngoài ra không tải chậm xảy ra ở đây (nó thực sự không thể nếu bạn tắt nó và nếu bạn vô hiệu hóa ngay cả proxy động) khi bạn truy cập program.Programsprogram.OwnerProgram thuộc tính điều hướng.

Thuộc tính điều hướng được điền khi kết quả từ truy vấn của bạn được thực hiện vì truy vấn của bạn (tải tất cả chương trình) sẽ tải tất cả các chương trình mà thuộc tính điều hướng có thể tham chiếu. EF phát hiện ra rằng những thực thể liên quan đã có trong bộ nhớ và đưa chúng vào các thuộc tính điều hướng một cách tự động.

Bạn có thể xác minh điều này nếu bạn không tải tất cả chương trình nhưng mà thôi, ví dụ, một duy nhất:

Program program = _dbContext.Programs.FirstOrDefault(); 

Bây giờ, program.Programsprogram.OwnerProgram sẽ null - trừ khi nạp program là một phần bộ sưu tập của riêng mình là program.OwnerProgram hoặc là riêng của mình OwnerProgram.

+1

Cảm ơn bạn, đây là những gì tôi thấy. Có cách nào tôi có thể làm cho EF không tải thuộc tính điều hướng trừ khi tôi đang sử dụng .Bao gồm()? – gixen

+0

@gixen: Như đã nói, nó không thực sự "tải". Sửa lỗi mối quan hệ chỉ cần đặt các thực thể vào các bộ sưu tập dẫn hướng và các tham chiếu đã được tải anyway. Vì vậy, không có phí truy vấn. Nếu bạn muốn sửa đổi các thực thể sau khi tải, bạn cần theo dõi thay đổi và bạn không thể tắt hành vi này. Nếu không theo dõi thay đổi trong các tình huống chỉ đọc, bạn có thể thử '_dbContext.Programs.AsNoTracking(). ToList()'. Nhưng tôi không chắc chắn nếu nó sẽ giúp đỡ trong trường hợp này. – Slauma

+0

Những gì tôi nhận được từ câu trả lời này là không có cách nào để tải toàn bộ đồ thị đối tượng trong EF mà không có bối cảnh mở cho các thuộc tính điều hướng tải lười. OR .Include ("NavigationProtperyName") có thể được gọi một cách rõ ràng để tải thuộc tính Điều hướng, nhưng nó được yêu cầu trên mỗi truy vấn. –

2

"EF vẫn tải Programs and OwnerProgram thuộc tính của Chương trình lớp"

Đây là hành vi đúng, nhưng thay vì tải các tài sản chuyển hướng một cách lười biếng, nó tải chúng háo hức.

Điều này có nghĩa là các truy vấn cơ sở dữ liệu cần thiết để truy xuất giá trị thuộc tính điều hướng được thực hiện ngay khi thực thể Program được truy xuất và thuộc tính điều hướng được điền.

Khi LazyLoadingEnabled được đặt thành true các truy vấn này không được kích hoạt cho đến khi bạn cố truy cập các thuộc tính điều hướng. Điều này cũng áp dụng khi bạn di chuột qua các thuộc tính điều hướng và trình gỡ rối được đính kèm, điều này có thể khiến bạn nghĩ rằng các thực thể không được tải một cách lười biếng khi thực tế chúng là - trình gỡ lỗi đang truy cập thuộc tính điều hướng, vì vậy Entity Framework tải nó.

Bạn có thể chạy trình lược tả SQL như this one để xem chính xác thời điểm các truy vấn được kích hoạt khi bạn gỡ lỗi mã của mình.

0

Với mẫu trên, EF vẫn tải các thuộc tính Chương trình và Chủ sở hữu của lớp Chương trình. Tôi đã thử xóa các từ khóa ảo, tắt tạo proxy và cũng đã xác minh rằng LazyLoadingEnabled = false trên chính Mẫu đó.

Tôi có thiếu gì đó không?

Bạn cần xóa hàm tạo mặc định để khởi tạo các thuộc tính này.

Các vấn đề liên quan