Quels sont les inconvénients à désactiver ProxyCreationEnabled pour CTP5 du code EF?

La seule façon dont mon service WCF peut renvoyer des classes à partir d’un premier modèle de code consiste à définir le paramètre ProxyCreationEnable sur false à l’aide du code ci-dessous.

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

Quelles sont les conséquences négatives de cela? Un avantage est que je peux au moins obtenir ces types dynamics sérialisés afin qu’ils puissent être envoyés sur le fil en utilisant WCF.

Les proxies dynamics sont utilisés pour le suivi des modifications et le chargement différé. Lorsque WCF tente de sérialiser un object, le contexte associé est généralement fermé et éliminé, mais la sérialisation des propriétés de navigation déclenchera automatiquement un chargement différé (sur un contexte fermé) => exception.

Si vous désactivez le chargement différé, vous devrez utiliser un chargement rapide pour toutes les propriétés de navigation que vous souhaitez utiliser (Include sur ObjectQuery). Le suivi des modifications ne fonctionne pas sur WCF. Il ne fonctionne que pour la modification de l’entité associée à ObjectContext.

Si DbContext.Configuration.ProxyCreationEnabled est défini sur false , DbContext ne charge pas les objects enfants pour un object parent, sauf si la méthode Include est appelée sur l’object parent. Définir DbContext.Configuration.LazyLoadingEnabled sur true ou false n’aura aucun impact sur ses comportements.

Si DbContext.Configuration.ProxyCreationEnabled est défini sur true , les objects enfants seront chargés automatiquement et la valeur DbContext.Configuration.LazyLoadingEnabled contrôlera le moment où les objects enfants seront chargés.

Lorsque vous utilisez EF, il crée un proxy par défaut pour votre classe. Une solution peut être d’append cette ligne dans le constructeur de votre classe DbContext. Votre modèle de données hérité de la classe DbContext, vous pouvez donc modifier votre modèle comme suit:

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

Cette classe est dans votre EF.edmx puis dans yourmodel.Context.tt puis yourmodel.Context.cs

(Utilisation de Visual Studio 2013 ou version ultérieure)

Pour éviter la modification du constructeur de classe dans votre modèle EF chaque fois que vous actualisez le modèle à partir de la firebase database ou déclenchez la reconstruction du code d’une autre manière, l’emplacement approprié pour effectuer la modification se trouve dans le fichier de code T4 responsable de créer réellement le code du modèle. Il y a quelques années, j’ai eu un autre problème avec les propriétés dynamics lorsque j’ai compris les mécanismes sous-jacents de la création des classes et des propriétés. T4 !!! Quel miracle c’est: – La syntaxe T4 D peut être un peu intimidante au début, donc la lecture de la syntaxe est sage. Être très concentré lors des modifications est également une bonne idée 🙂

Alors! Si vous regardez dans votre modèle, vous avez un fichier .tt sous votre fichier .edmx. Ce fichier .tt (T4) est le script qui crée votre classe de modèle. Le script sera exécuté automatiquement chaque fois que vous construirez votre modèle ou apporterez des modifications à l’éditeur de modèle.

Disons que votre descripteur de modèle s’appelle Model1.edmx . Vous aurez un fichier nommé Model1.Context.tt dans l’arborescence sous celui-ci. Vous verrez également un fichier Model1.Context.cs . Ceci est évidemment le fichier de code réel pour votre contexte. Mais ce fichier est le résultat du fichier de script .tt en cours d’exécution ! Il est complètement créé dynamicment. Donc, aucune idée de le modifier.

Ouvrez le fichier .tt et vous verrez quelque chose comme:

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

Une cinquantaine de lignes plus loin, le code constructeur est en cours de script.

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

J'ai ajouté la propriété base.Configuration.ProxyCreationEnabled = false; pour que ce soit la toute première ligne du constructeur.

Enregistrez votre fichier et ouvrez le fichier Model1.Context.cs pour voir le code résultant. Si vous souhaitez forcer l'exécution du script de modèle, sélectionnez le menu

Build - Transformez tous les modèles T4

Il est facile de savoir si vous avez commis une erreur dans votre code T4, car le fichier .cs ne sera pas créé du tout ou avec des erreurs évidentes si vous l'ouvrez dans l'éditeur.