Entiendo la frustración de los OP, este uso de virtual no es para la abstracción con plantilla para la que el modificador virtual de facto es efectivo.
Si alguno todavía está luchando con esto, ofrecería mi punto de vista, ya que trato de mantener las soluciones simples y la jerga al mínimo:
Entity Framework en una pieza simple utiliza carga diferida, que es el equivalente de preparar algo para la ejecución futura. Eso se ajusta al modificador 'virtual', pero hay más en esto.
En Entity Framework, el uso de una propiedad de navegación virtual le permite denotarlo como el equivalente de una Clave externa anulable en SQL. No tiene que unirse con entusiasmo a todas las tablas con clave cuando realiza una consulta, pero cuando necesita la información, se vuelve impulsada por la demanda.
También mencioné anulable porque muchas propiedades de navegación no son relevantes al principio. es decir, en un escenario de cliente / pedidos, no tiene que esperar hasta el momento en que se procesa un pedido para crear un cliente. Se puede, pero si tuviera un proceso de varias etapas para lograr esto, es posible encontrar la necesidad de persistir los datos de los clientes para la finalización de plazo o para su implementación en futuros pedidos. Si se implementaran todas las propiedades de navegación, tendría que establecer cada clave externa y campo relacional en el guardado. Eso realmente solo restablece los datos en la memoria, lo que anula el papel de la persistencia.
Entonces, aunque puede parecer críptico en la ejecución real en tiempo de ejecución, he encontrado que la mejor regla general para usar sería: si está generando datos (leyendo en un Modelo de visualización o Modelo serializable) y necesita valores antes de las referencias, no usar virtual; Si su alcance es la recopilación de datos que pueden estar incompletos o la necesidad de buscar y no requieren que todos los parámetros de búsqueda se completen para una búsqueda, el código hará un buen uso de la referencia, de manera similar al uso de las propiedades de valor anulables int? ¿largo?. Además, abstraer su lógica de negocios de su recopilación de datos hasta la necesidad de inyectarla tiene muchos beneficios de rendimiento, similar a crear instancias de un objeto y comenzarlo desde cero. Entity Framework utiliza mucha reflexión y dinámica, lo que puede degradar el rendimiento, y la necesidad de tener un modelo flexible que se pueda adaptar a la demanda es fundamental para gestionar el rendimiento.
Para mí, eso siempre tuvo más sentido que usar jerga tecnológica sobrecargada como representantes, delegados, controladores y demás. Una vez que llegas a tu tercera o cuarta programación lang, puede ser complicado con estos.