Önce EF kodunun CTP5'i için ProxyCreationEnabled'ı kapatmanın olumsuz yönleri nelerdir?


82

Benim WCF hizmeti bir kod birinci modelden sınıfları dönebilmek tek yolu ayarlayarak olduğu ProxyCreationEnableiçin falseaşağıdaki kodu kullanarak.

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

Bunu yapmanın olumsuz sonuçları nelerdir? Kazançlardan biri, en azından bu dinamik türleri serileştirebilirim, böylece WCF kullanarak kablo üzerinden gönderilebilirler.

Yanıtlar:


71

Dinamik proxy'ler, değişiklik izleme ve geç yükleme için kullanılır. WCF nesneyi serileştirmeye çalıştığında, ilgili bağlam genellikle kapatılır ve atılır, ancak gezinme özelliklerinin serileştirilmesi otomatik olarak geç yüklemeyi (kapalı bağlamda) => istisna tetikler.

Geç yüklemeyi kapatırsanız, kullanmak istediğiniz tüm gezinme özellikleri için istekli yüklemeyi kullanmanız gerekecektir (ObjectQuery'ye Dahil Et). İzleme değişiklikleri WCF üzerinden çalışmaz, yalnızca ObjectContext'e eklenen varlığın değiştirilmesi için çalışır.


7
ProxyCreationEnabled'ı devre dışı bırakmanın bir performans avantajı var mı? Örneğin, istekli yükleme ile okuma yapmak için sık sık bir DbContext örneği alırım.
Chris Moschini

2
@ChrisMoschini "Bir POCO varlığı değişiklik izleme proxy'sine sahip olmadığında, varlıklarınızın içeriği önceki kaydedilmiş bir durumun kopyasıyla karşılaştırılarak değişiklikler bulunur. Bu derin karşılaştırma, bağlamınızda çok sayıda varlığa sahip olduğunuzda uzun bir süreç haline gelecektir. veya varlıklarınız çok büyük miktarda mülke sahipse, son karşılaştırmadan bu yana hiçbiri değişmemiş olsa bile. " msdn.microsoft.com/en-us/library/hh949853(v=vs.113).aspx
Niklas Peter

75

Olarak DbContext.Configuration.ProxyCreationEnabledayarlanırsa false, DbContext üst nesnede Includeyöntem çağrılmadıkça bazı üst nesneler için alt nesneleri yüklemeyecektir . Ayar DbContext.Configuration.LazyLoadingEnablediçin trueya falseda davranışlar üzerinde herhangi bir etkiye sahip olacaktır.

Olarak DbContext.Configuration.ProxyCreationEnabledayarlanırsa true, alt nesneler otomatik olarak yüklenecek ve DbContext.Configuration.LazyLoadingEnableddeğer , alt nesnelerin ne zaman yükleneceğini kontrol edecektir.


10

EF kullandığınızda, sınıfınız için varsayılan olarak bir proxy oluşturur. Bu satırı DbContext sınıfınızın yapıcısına eklemek bir çözüm olabilir. Veri modeliniz DbContext sınıfından miras alınmıştır, böylece modelinizi şu şekilde düzenleyebilirsiniz:

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

Bu sınıf Sepetinde olduğu EF.edmxsonra yourmodel.Context.ttsonrayourmodel.Context.cs


2
Bu bir cevap değil ama yine de bana yardımcı oldu.
Akira Yamamoto

1
Bu sıraya koyma sürecini nasıl otomatikleştireceğiniz konusunda iyi bir öneriniz var mı? Bir modeli her yeniden oluşturduğumda, kesinlikle özelliği yanlış olarak ayarlamayı unutmak zorunda kalırım ve bu, birisi neyin yanlış olduğunu anlamadan önce saatlerce hata ayıklama alabilir.
Konrad Viltersten

@konrad - Kodu, geçersiz kılınmaması için kısmi bir sınıfta oluşturun. public kısmi sınıf yourDataMoldelEntities ()
Mikee

@Mikee Gerçekten mi? Kısmi sınıfta yazdığımla otomatik olarak oluşturulan
kurucunun

@konrad, kodunuzun üzerine yazılmaması için kısmi bir sınıf 'type'ı yarattılar
Mikee

6

(Visual Studio 2013 veya sonraki bir sürümünü kullanarak)

Modeli veritabanından her yenilediğinizde veya başka bir yolla kodun yeniden oluşturulmasını tetiklediğinizde EF modelinizdeki sınıf oluşturucunun düzenlenmesini önlemek için, değişikliği yapmak için uygun yer sorumlu olan T4 kod dosyasındadır. aslında model kodunu oluşturmak. Birkaç yıl önce, sınıfların ve özelliklerin gerçekte nasıl yaratıldığının altında yatan mekaniği anladığımda, dinamik özelliklerle ilgili başka bir sorun yaşadım. T4 !!! Bu ne bir mucize: -D T4 sözdizimi ilk başta biraz korkutucu olabilir, bu yüzden sözdizimini okumak akıllıca olacaktır. Değişiklik yaparken ÇOK odaklanmak da iyi bir fikir :-)

Yani! Modelinize bakarsanız, .edmx dosyanızın altında bir .tt dosyanız vardır. Bu .tt (T4) dosyası, aslında model sınıfınızı oluşturan komut dosyasıdır. Modelinizi her oluşturduğunuzda veya model düzenleyicide bazı değişiklikler yaptığınızda komut dosyası otomatik olarak çalıştırılacaktır.

Model tanımlayıcınızın Model1.edmx olarak adlandırıldığını varsayalım . Altındaki ağaçta Model1.Context.tt adlı bir dosyanız olacaktır . Ayrıca bir Model1.Context.cs dosyası göreceksiniz . Bu kesinlikle bağlamınız için gerçek kod dosyasıdır. Ancak bu dosya, çalıştırılan .tt komut dosyasının sonucudur ! Tamamen dinamik olarak yaratılmıştır. Yani onu düzenleme fikri yok.

.Tt dosyasını açın ve şöyle bir şey göreceksiniz:

<#@ 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);
..
..

50 veya daha fazla satır aşağıya, kurucu kodu betik yazılıyor.

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;
    <#
    }

base.Configuration.ProxyCreationEnabled = false;Yapıcıdaki ilk satır olacak şekilde özelliği ekledim .

Dosyanızı kaydedin ve elde edilen kodu görmek için Model1.Context.cs dosyasını açın. Şablon komut dosyasını çalıştırmaya zorlamak istiyorsanız, menüyü seçin

Oluştur - Tüm T4 şablonlarını dönüştürün

T4 kodunuzda bir hata yapıp yapmadığınızı bilmek kolaydır, çünkü .cs dosyası ya hiç yapılmayacaktır ya da düzenleyicide açarsanız bariz hatalar olacaktır.


Vay canına - sorunu kökünden düzelttiği için bu gerçekten tercih edilen çözüm olmalı. Ayrıca, * .tt dosyasının sonuçta ortaya çıkan * .cs dosyasıyla ilişkisi hakkında iyi bir arka plan sağlar.
Douglas Timms
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.