65

Ai đó có thể đưa ra một số lời khuyên hoặc chỉ ra một số blog/bài viết có thể giúp đưa ra quyết định này? Các proxy có vẻ rất xa lạ với tôi và tôi do dự khi sử dụng chúng. Tôi thích khả năng kiểm soát Tải Lười biếng bằng cách sử dụng các thuộc tính ảo trong mô hình của tôi, nhưng đó là tất cả những lợi ích mà tôi có thể thấy. Ứng dụng của tôi là một ứng dụng web MVC đơn giản và tôi không cần phải nối dây bất kỳ móc nào vào ngữ cảnh khi các thực thể trải nghiệm trạng thái thay đổi.Tôi có nên bật hoặc tắt proxy động với khung thực thể 4.1 và MVC3 không?

Dù sao, đây là danh sách rất hạn chế về ưu và nhược điểm của tôi ngay bây giờ, hãy cho tôi biết nếu tôi không có cơ sở với bất kỳ điều nào trong số này.

Ưu

  • On 'Lưu' hoặc 'Cập nhật', tôi nhận được liền mạch với
  • Lazy-Loading cấu hình 'Apply'Changes' là rất dễ dàng.

Nhược điểm

  • proxy Không bao giờ sử dụng trước cho các đơn vị của tôi, đây là một sự thay đổi trong cách tiếp cận rằng chỉ có vẻ không thoải mái cho bản thân mình và đội ngũ đồng thành viên.
  • Lúng túng để gỡ lỗi.
  • Yêu cầu mã bổ sung nếu tôi muốn serialize/de-serialize
  • Khi 'Lưu' hoặc 'Cập nhật', proxy phải là cùng một đối tượng được truy xuất từ ​​ngữ cảnh.
+5

+1 - Sự cố serialization/deserialization là một nỗi đau! – StuartLC

Trả lời

101

Nếu bạn nói về proxy động trong EF có hai loại khác nhau để phân biệt:

  • proxy để tải lười biếng
  • Proxies cho sự thay đổi theo dõi

Thường là theo dõi sự thay đổi Proxy cũng có thể phục vụ như một proxy cho tải chậm. Điều ngược lại là không đúng sự thật. Điều này là do yêu cầu về proxy theo dõi thay đổi cao hơn, đặc biệt là tất cả các thuộc tính - cũng là thuộc tính vô hướng - phải là virtual. Để tải chậm, điều đó đủ để các thuộc tính điều hướng là virtual.

Thực tế là một sự thay đổi theo dõi Proxy luôn cũng cho phép tận dụng tải lười biếng là lý do chính tại sao DbContext có cờ cấu hình này:

DbContext.Configuration.LazyLoadingEnabled 

Cờ này là đúng theo mặc định. Đặt nó thành false sẽ tắt tải chậm ngay cả khi proxy được tạo. Điều này đặc biệt quan trọng nếu bạn đang làm việc với proxy thay đổi theo dõi nhưng không muốn sử dụng những proxy đó để tải xuống chậm.

Tùy chọn ...

DbContext.Configuration.ProxyCreationEnabled 

... vô hiệu hóa việc tạo ủy quyền hoàn toàn - để theo dõi sự thay đổi và tải lười biếng là tốt.

Cả hai cờ chỉ có ý nghĩa nếu tất cả các lớp thực thể của bạn đáp ứng các yêu cầu để tạo theo dõi thay đổi hoặc proxy tải chậm.

Bây giờ, bạn biết mục đích của proxy tải động chậm. Vì vậy, tại sao một người nên sử dụng proxy theo dõi thay đổi động?

Thực ra, lý do duy nhất tôi biết là hiệu suất. Nhưng đây là một lý do rất mạnh. Việc so sánh theo dõi thay đổi dựa trên proxy với sự thay đổi theo dõi dựa trên proxy là khác nhau - từ các phép đo của tôi, hệ số 50 đến 100 là thực tế (lấy từ một phương pháp cần khoảng một giờ cho 10000 lần theo dõi thay đổi dựa trên chụp nhanh và 30 đến 60 giây sau khi thực hiện tất cả các thuộc tính ảo để bật proxy theo dõi thay đổi). Điều này là nhận được một yếu tố quan trọng nếu bạn có một số ứng dụng mà quá trình và thay đổi nhiều (nói hơn 1000) thực thể. Trong một ứng dụng web, nơi bạn có thể chỉ có các hoạt động Tạo/Thay đổi/Xóa trên các thực thể đơn lẻ trong một yêu cầu web, sự khác biệt này không quan trọng lắm.

Trong hầu hết các trường hợp, bạn có thể tận dụng tải mong muốn hoặc explicite để đạt được mục tiêu tương tự nếu bạn không muốn làm việc với proxy tải chậm. Hiệu suất cho tải dựa trên proxy tải chậm hoặc proxy không dựa trên proxy là giống nhau vì về cơ bản cùng một truy vấn xảy ra khi các thuộc tính điều hướng được tải - trong trường hợp đầu tiên proxy thực hiện truy vấn, trong trường hợp thứ hai mã viết tay của bạn. Vì vậy, bạn có thể sống mà không cần tải proxy lười biếng mà không làm mất nhiều. Nếu bạn muốn hiệu suất hợp lý để xử lý nhiều, nhiều thực thể không có thay thế cho thay đổi proxy theo dõi - ngoài việc sử dụng EntityObject thực thể có nguồn gốc trong EF 4.0 (không phải là tùy chọn trong EF 4.1 vì nó bị cấm khi bạn sử dụng DbContext) hoặc không sử dụng Entity Framework.

Chỉnh sửa (tháng 5 năm 2012)

Trong khi chờ đợi tôi đã học được rằng có những tình huống mà change tracking proxies không nhanh hơn hoặc thậm chí tồi tệ hơn trong hiệu suất so với ảnh chụp theo dõi dựa.

Do các biến chứng này khi sử dụng proxy theo dõi thay đổi, cách ưa thích là sử dụng theo dõi thay đổi dựa trên chụp nhanh theo mặc định và sử dụng proxy cẩn thận (sau khi thực hiện một số kiểm tra). nhanh hơn so với theo dõi thay đổi dựa trên ảnh chụp nhanh.

+1

@Slauma - Tôi không biết bạn có thể thay đổi những cấu hình đó khi đang di chuyển và nghĩ rằng nó chỉ khả dụng khi tạo các định nghĩa miền. Sử dụng 'if (DisableProxy) { context.Configuration.ProxyCreationEnabled = false; context.Configuration.LazyLoadingEnabled = false; } 'Tôi có thể cho phép các proxy động này khả dụng để được tuần tự hóa mà không gây ra lỗi tham chiếu vòng tròn. Cảm ơn! +1 –

15

Đối với bất kỳ ai sử dụng Khung thực thể 5, hãy nhớ xem bài viết Performance Considerations. Sections 5 NoTracking Queries8 Loading Related Entities cung cấp thông tin bạn cần để đưa ra quyết định sáng suốt. Chúc mừng.

2

Tôi khuyên bạn KHÔNG nên sử dụng proxy. Việc tạo proxy động phá vỡ hoặc tạo ra các biến chứng cho các thành phần phụ thuộc vào việc kiểm tra kiểu thời gian chạy. Ví dụ:

Trình tự động sẽ loại lỗi không khớp loại/không mong muốn trong thời gian chạy vì thực thể của bạn sẽ có loại proxy được tạo động trong thời gian chạy chứ không phải loại bạn đã nhập khi định cấu hình tự động.

+1

Máy tự động chính xác là lý do tại sao tôi bắt đầu xem xét vấn đề này và nhược điểm của khả năng chuyển proxy động. – FRoZeN

+0

Tôi đã phát triển ghét toàn bộ khái niệm về proxy động. Thứ nhất, các vấn đề liên quan đến proxy chỉ hiển thị trong thời gian chạy. Thông thường, chỉ trong sản xuất khi điều kiện không rõ ràng được đáp ứng (thường sẽ bị trượt bởi người thử nghiệm). Thứ hai, nó là một trừu tượng bị rò rỉ, vì việc gọi mã thường phải nhận thức được sự hiện diện, và các nhu cầu đặc biệt, của các proxy. Tôi đã từ bỏ toàn bộ khái niệm, tắt nó đi, và cập nhật thiết kế của tôi - và chưa bao giờ nhìn lại. Các proxy động nên được chụp ở phía sau đầu. –

+2

Bạn bè không cho phép bạn bè sử dụng proxy động. –

0

Mặc dù proxy động có một vài tính năng đẹp, trong thực tế chúng có thể tạo ra nhiều lỗi lạ và tối nghĩa. Ví dụ như giữ một biến riêng của một thực thể trong một trong các lớp của tôi (nó đã được thực hiện một quá trình lô) và tôi đã lặp qua một vài triệu bản ghi, xử lý và chèn chúng theo lô, tái tạo bối cảnh dữ liệu mỗi n-hồ sơ để làm sạch bộ nhớ.Mặc dù tôi KHÔNG BAO GIỜ sử dụng biến riêng, EF đã liên kết nó với các đối tượng mới của tôi (có một tham chiếu thông qua một thuộc tính điều hướng) mặc dù tôi chỉ thiết lập Id tham chiếu.

Điều này khiến tất cả các đối tượng vẫn còn trong bộ nhớ trong suốt quá trình chạy. Tôi đã phải sử dụng AsNoTracking và vô hiệu hoá proxy để quá trình hoạt động như mong đợi và bộ nhớ và hiệu suất trở lại mức bình thường. Hãy nhớ rằng proxy cũng tham chiếu đến bối cảnh tạo ra chúng và điều này có thể lưu giữ trong bộ nhớ đồ thị khổng lồ của các thực thể, gần như không thể gỡ lỗi nó

Vì vậy, tôi tin rằng bạn nên vô hiệu hóa toàn bộ proxy và kích hoạt chúng và chứa các đoạn mã. Nó là rất nguy hiểm và không thể gỡ lỗi các vấn đề như vậy expecially khi bạn có các đội lớn mã hóa.

Theo dõi thay đổi đẹp, có thể biện minh cho việc sử dụng ở một số nơi. Việc tải lười biếng có thể là một vấn đề lớn về hiệu suất và tuần tự hóa trừ khi bạn biết bạn đang làm gì. Tôi thích tải háo hức hoặc rõ ràng mọi lúc.

0

Sử dụng Automapper 4.2.1. Phiên bản mới không có DynamicMap

var parents = parentsRepo.GetAll().ToList(); 
Mapper.CreateMap<Parent,ParentDto>(); 
var parentsDto = Mapper.DynamicMap<List<ParentDto>>(parents); 
Các vấn đề liên quan