Nhược điểm của việc tắt ProxyCreationEnabled cho CTP5 của mã EF trước là gì


82

Cách duy nhất mà dịch vụ WCF của tôi có thể trả về các lớp từ mô hình đầu tiên mã là bằng cách đặt ProxyCreationEnablethành falsesử dụng mã bên dưới.

((IObjectContextAdapter)MyDb).ObjectContext.ContextOptions.ProxyCreationEnable = false;

Những hậu quả tiêu cực của việc làm này là gì? Một lợi ích là tôi ít nhất có thể nhận được các loại động này được tuần tự hóa để chúng có thể được gửi qua dây bằng cách sử dụng WCF.

Câu trả lời:


71

Proxy động được sử dụng để theo dõi thay đổi và tải chậm. Khi WCF cố gắng tuần tự hóa đối tượng, ngữ cảnh liên quan thường được đóng và xử lý nhưng việc tuần tự hóa các thuộc tính điều hướng sẽ tự động kích hoạt tải chậm (trên ngữ cảnh đóng) => ngoại lệ.

Nếu bạn tắt tính năng tải chậm, bạn sẽ cần sử dụng tính năng tải háo hức cho tất cả các thuộc tính điều hướng bạn muốn sử dụng (Bao gồm trên ObjectQuery). Theo dõi các thay đổi không hoạt động trên WCF, nó chỉ hoạt động để sửa đổi thực thể được đính kèm với ObjectContext.


7
Có lợi ích về hiệu suất khi tắt ProxyCreationEnabled không? Ví dụ, tôi thường lấy một phiên bản DbContext chỉ để đọc với tải nhanh.
Chris Moschini

2
@ChrisMoschini "Khi một thực thể POCO không có proxy theo dõi thay đổi, các thay đổi được tìm thấy bằng cách so sánh nội dung của các thực thể với bản sao của trạng thái đã lưu trước đó. So sánh sâu này sẽ trở thành một quá trình dài khi bạn có nhiều thực thể trong ngữ cảnh của mình hoặc khi các thực thể của bạn có rất nhiều thuộc tính, ngay cả khi không có thuộc tính nào thay đổi kể từ lần so sánh cuối cùng diễn ra. " msdn.microsoft.com/en-us/library/hh949853(v=vs.113).aspx
Niklas Peter

75

Nếu DbContext.Configuration.ProxyCreationEnabledđược đặt thành false, DbContext sẽ không tải các đối tượng con cho một số đối tượng mẹ trừ khi Includephương thức được gọi trên đối tượng mẹ. Đặt DbContext.Configuration.LazyLoadingEnabledthành truehoặc falsesẽ không ảnh hưởng đến hành vi của nó.

Nếu DbContext.Configuration.ProxyCreationEnabledđược đặt thành true, các đối tượng con sẽ được tải tự động và DbContext.Configuration.LazyLoadingEnabledgiá trị sẽ kiểm soát thời điểm các đối tượng con được tải.


10

Khi bạn sử dụng EF, nó tạo proxy theo mặc định cho lớp của bạn. Một giải pháp có thể là thêm dòng này trong hàm tạo của lớp DbContext của bạn. Mô hình dữ liệu của bạn được kế thừa từ lớp DbContext, vì vậy bạn có thể chỉnh sửa mô hình của mình như sau:

    public yourDataModelEntities()
        : base("name=yourDataModelEntities")
    {
        base.Configuration.ProxyCreationEnabled = false;
    }

Lớp học này là của bạn EF.edmxsau yourmodel.Context.ttđóyourmodel.Context.cs


2
Đây không phải là một câu trả lời nhưng nó đã giúp tôi dù sao.
Akira Yamamoto

1
Bạn có gợi ý hay về cách tự động hóa quy trình đưa vào dòng đó không? Mỗi khi tôi tạo lại một mô hình, tôi chắc chắn sẽ quên đặt thuộc tính thành false và điều đó có thể mất hàng giờ gỡ lỗi trước khi ai đó nhận ra điều gì sai với nó.
Konrad Viltersten

@konrad - Tạo mã trong một lớp từng phần để nó không bị ghi đè. public một phần lớp yourDataMoldelEntities ()
Mikee

@Mikee Thật không? Tôi mong chờ một số loại vấn đề do các nhà xây dựng tự động tạo ra va chạm với một trong những văn bản của tôi trong lớp một phần ...
Konrad Viltersten

@ Konrad họ đã tạo ra một phần lớp 'type' để cung cấp cho bạn một wayto không có mã của bạn ghi đè
Mikee

6

(Sử dụng Visual Studio 2013 trở lên)

Để tránh việc chỉnh sửa hàm tạo lớp trong mô hình EF của bạn mỗi khi bạn làm mới mô hình từ cơ sở dữ liệu hoặc một số cách khác kích hoạt xây dựng lại mã, vị trí thích hợp để thực hiện thay đổi là trong tệp mã T4 chịu trách nhiệm thực sự tạo mã mô hình. Tôi đã gặp một số vấn đề khác với các thuộc tính động một vài năm trước khi tôi hiểu cơ chế cơ bản về cách các lớp và thuộc tính thực sự được tạo ra. T4 !!! Thật là kỳ diệu: Cú pháp-D T4 thoạt đầu có thể hơi đáng sợ, vì vậy việc đọc kỹ cú pháp là điều khôn ngoan. RẤT tập trung khi thực hiện thay đổi cũng là một ý kiến ​​hay :-)

Vì thế! Nếu bạn nhìn vào mô hình của mình, bạn có tệp .tt dưới tệp .edmx của bạn. Tệp .tt (T4) này là tập lệnh thực sự tạo ra lớp mô hình của bạn. Tập lệnh sẽ được chạy tự động mỗi khi bạn xây dựng mô hình của mình hoặc thực hiện một số thay đổi trong trình chỉnh sửa mô hình.

Giả sử bộ mô tả Mô hình của bạn có tên là Model1.edmx . Bạn sẽ có một tệp có tên Model1.Context.tt trong cây bên dưới nó. Bạn cũng sẽ thấy tệp Model1.Context.cs . Đây rõ ràng là tệp mã thực cho ngữ cảnh của bạn. Nhưng tệp này là kết quả của tệp kịch bản .tt đang được chạy ! Nó được tạo hoàn toàn động. Vì vậy, không có ý tưởng chỉnh sửa nó.

Mở tệp .tt và bạn sẽ thấy một cái gì đó như:

<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
 output extension=".cs"#><#

const string inputFile = @"Model1.edmx";
var textTransform = DynamicTextTransformation.Create(this);
..
..

Còn khoảng 50 dòng nữa, mã khởi tạo đang được tập lệnh.

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
<#
}
#>

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
    {
        public <#=code.Escape(container)#>()
            : base("name=<#=container.Name#>")
        {
        base.Configuration.ProxyCreationEnabled = false;
    <#
    if (!loader.IsLazyLoadingEnabled(container))
    {
    #>
            this.Configuration.LazyLoadingEnabled = false;
    <#
    }

Tôi đã thêm thuộc tính base.Configuration.ProxyCreationEnabled = false;để nó sẽ là dòng đầu tiên trong hàm tạo.

Lưu tệp của bạn và mở tệp Model1.Context.cs để xem mã kết quả. Nếu bạn muốn buộc chạy tập lệnh mẫu, hãy chọn menu

Xây dựng - Định dạng tất cả các mẫu T4

Thật dễ dàng để biết liệu bạn có mắc lỗi trong mã T4 của mình hay không, vì tệp .cs sẽ hoàn toàn không được tạo hoặc có lỗi rõ ràng nếu bạn mở nó trong trình chỉnh sửa.


Chà - đây thực sự nên là giải pháp ưu tiên vì nó khắc phục được sự cố tận gốc. Và cũng cung cấp nền tảng tốt về mối quan hệ của tệp * .tt với tệp * .cs kết quả.
Douglas Timms
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.