Si l'on parle de proxies dynamiques dans EF, il faut en distinguer deux types différents :
- Proxies pour le chargement paresseux
- Proxies pour le suivi des changements
En général, un proxy de suivi des modifications peut également servir de proxy pour le chargement paresseux. L'inverse n'est pas vrai. En effet, les exigences pour les mandataires de suivi des modifications sont plus élevées, notamment todo les propriétés - également les propriétés scalaires - doivent être virtual
. Pour le chargement paresseux, il suffit que les propriétés de navigation soient virtual
.
Le fait qu'un proxy de suivi des modifications permette également de tirer parti du chargement paresseux est la principale raison pour laquelle le DbContext dispose de cet indicateur de configuration :
DbContext.Configuration.LazyLoadingEnabled
Ce drapeau est vrai par défaut. En lui donnant la valeur false
désactive le chargement paresseux même si des proxies sont créés. Ceci est particulièrement important si vous travaillez avec des proxies de suivi des modifications mais que vous ne voulez pas utiliser ces proxies pour le chargement paresseux également.
L'option ...
DbContext.Configuration.ProxyCreationEnabled
... désactive complètement la création de proxy - pour le suivi des changements et le chargement paresseux également.
Ces deux drapeaux n'ont de sens que si vos classes d'entités répondent aux exigences de création de proxies de suivi des modifications ou de chargement paresseux.
Maintenant, vous connaissez l'utilité des proxies dynamiques à chargement paresseux. Alors, pourquoi utiliser des proxies dynamiques de suivi des modifications ?
En fait, la seule raison que je connaisse est performance . Mais c'est une raison très forte. Si l'on compare le suivi des modifications basé sur les instantanés avec le suivi des modifications basé sur les mandataires, la différence de performance est énorme - d'après mes mesures, un facteur de 50 à 100 est réaliste (d'après une méthode qui nécessitait environ une heure pour 10000 entités avec le suivi des modifications basé sur les instantanés et 30 à 60 secondes après avoir rendu toutes les propriétés virtuelles pour activer les mandataires de suivi des modifications). Cela devient un facteur important si vous avez une application qui traite et modifie de nombreuses entités (disons plus de 1000). Dans une application web où il est possible que vous n'ayez que des opérations de création/modification/suppression sur des entités uniques dans une requête web, cette différence n'est pas si importante.
Dans presque toutes les situations, vous pouvez tirer parti du chargement rapide ou explicite pour atteindre le même objectif si vous ne voulez pas travailler avec des mandataires de chargement paresseux. Les performances du chargement paresseux basé sur un proxy ou du chargement explicite basé sur un non-proxy sont les mêmes, car la même requête est effectuée lors du chargement des propriétés de navigation - dans le premier cas, c'est le proxy qui effectue la requête, dans le second, c'est votre code écrit à la main. Ainsi, vous pouvez vivre sans les proxys de chargement paresseux sans perdre beaucoup.
Mais si vous souhaitez obtenir des performances raisonnables pour traiter un très grand nombre d'entités, il n'y a pas d'autre solution que de changer les mandataires de suivi - à part l'utilisation de l'option EntityObject
dans EF 4.0 (ce n'est pas une option dans EF 4.1 car c'est interdit lorsque l'on utilise des entités dérivées DbContext
) ou ne pas utiliser du tout Entity Framework.
Edit (mai 2012)
En attendant, j'ai appris qu'il y a des situations où Proxies de suivi des changements ne sont pas plus rapides, voire moins performants, par rapport au suivi basé sur les instantanés.
En raison de ces complications lors de l'utilisation de proxies de suivi des modifications, il est préférable d'utiliser par défaut le suivi des modifications basé sur les instantanés et d'utiliser les proxies avec précaution (après avoir effectué quelques tests) uniquement dans les situations où des performances élevées sont requises et où ils s'avèrent plus rapides que le suivi des modifications basé sur les instantanés.