No blog a seguir: http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
O blog contém o seguinte exemplo de código:
public class Dinner
{
public int DinnerID { get; set; }
public string Title { get; set; }
public DateTime EventDate { get; set; }
public string Address { get; set; }
public string HostedBy { get; set; }
public virtual ICollection<RSVP> RSVPs { get; set; }
}
public class RSVP
{
public int RsvpID { get; set; }
public int DinnerID { get; set; }
public string AttendeeEmail { get; set; }
public virtual Dinner Dinner { get; set; }
}
Qual é o propósito de usar virtual
ao definir uma propriedade em uma classe? Que efeito isso tem?
c#
class
properties
virtual
Gary Jones
fonte
fonte
Respostas:
Ele permite que o Entity Framework crie um proxy em torno da propriedade virtual para que a propriedade possa suportar carregamento lento e rastreamento de alterações mais eficiente. Consulte Que efeito (s) a palavra-chave virtual pode ter no Código POCO do Entity Framework 4.1 primeiro? para uma discussão mais aprofundada.
Edite para esclarecer "criar um proxy ao redor": Por "criar um proxy ao redor", estou me referindo especificamente ao que o Entity Framework faz. O Entity Framework exige que suas propriedades de navegação sejam marcadas como virtuais para que o carregamento lento e o rastreamento eficiente de alterações sejam suportados. Consulte Requisitos para criar proxies POCO .
O Entity Framework usa herança para oferecer suporte a essa funcionalidade, e é por isso que exige que certas propriedades sejam marcadas como virtuais em seus POCOs de classe base. Ele literalmente cria novos tipos derivados de seus tipos de POCO. Portanto, seu POCO está agindo como um tipo base para as subclasses criadas dinamicamente do Entity Framework. Isso é o que eu quis dizer com "criar um proxy".
As subclasses criadas dinamicamente que o Entity Framework cria tornam-se aparentes ao usar o Entity Framework em tempo de execução, não no tempo de compilação estática. E somente se você ativar os recursos de rastreamento lento de carregamento ou alteração do Entity Framework. Se você optar por nunca usar os recursos de rastreamento lento de carregamento ou alteração do Entity Framework (que não é o padrão), não será necessário declarar virtual nenhuma das propriedades de navegação. Você é responsável por carregar essas propriedades de navegação, usando o que o Entity Framework chama de "carregamento rápido" ou recuperando manualmente os tipos relacionados em várias consultas ao banco de dados. Você pode e deve usar os recursos de rastreamento lento de carregamento e alteração para as propriedades de navegação em muitos cenários.
Se você criar uma classe independente e marcar propriedades como virtuais, e simplesmente construir e usar instâncias dessas classes em seu próprio aplicativo, completamente fora do escopo do Entity Framework, suas propriedades virtuais não ganharão nada com isso. próprio.
Edite para descrever por que as propriedades seriam marcadas como virtuais
Propriedades como:
Não são campos e não devem ser considerados como tal. Eles são chamados de getters e setters e, no momento da compilação, são convertidos em métodos.
É por isso que eles são marcados como virtuais para uso no Entity Framework, pois permite que as classes criadas dinamicamente substituam as funções
get
e geradas internamenteset
. Se seus getter / setters de propriedades de navegação estiverem trabalhando para você no uso do Entity Framework, tente revisá-los para apenas propriedades, recompile e veja se o Entity Framework ainda pode funcionar corretamente:fonte
A
virtual
palavra-chave em C # permite que um método ou propriedade seja substituído por classes filho. Para obter mais informações, consulte a documentação do MSDN na palavra-chave 'virtual'.ATUALIZAÇÃO: Isso não responde à pergunta como atualmente solicitada, mas deixarei aqui para quem procura uma resposta simples para a pergunta original e não descritiva original.
fonte
virtual
propriedades por meio do Entity Framework - mesmo que isso não esteja explícito no título do OP. A resposta aceita é porque ela toca no lado das coisas do Entity Framework e como / por que asvirtual
propriedades são usadas nesse contexto.Entendo a frustração dos OPs, esse uso do virtual não é para a abstração modelada pela qual o modificador virtual defacto é eficaz.
Se alguém ainda está lutando com isso, eu ofereceria meu ponto de vista, ao tentar manter as soluções simples e o jargão no mínimo:
O Entity Framework em uma peça simples utiliza carregamento lento, o que equivale a preparar algo para execução futura. Isso se encaixa no modificador 'virtual', mas há mais para isso.
No Entity Framework, o uso de uma propriedade de navegação virtual permite denotá-la como o equivalente a uma Chave Externa anulável no SQL. Você não precisa ingressar ansiosamente em todas as tabelas com chave ao executar uma consulta, mas quando precisa das informações, elas se tornam orientadas pela demanda.
Mencionei também anulável porque muitas propriedades de navegação não são relevantes a princípio. ou seja, em um cenário de cliente / pedidos, você não precisa esperar até o momento em que um pedido é processado para criar um cliente. Você pode, mas se tiver um processo de várias etapas para conseguir isso, poderá encontrar a necessidade de persistir os dados do cliente para conclusão posterior ou para implantação em pedidos futuros. Se todas as propriedades de navegação foram implementadas, você teria que estabelecer todos os campos de chave estrangeira e relacional ao salvar. Isso realmente apenas coloca os dados de volta na memória, o que anula o papel da persistência.
Portanto, embora possa parecer enigmático na execução real em tempo de execução, eu achei a melhor regra geral a ser usada: se você estiver produzindo dados (lendo em um modelo de exibição ou modelo serializado) e precisar de valores antes das referências, não use virtual; Se o seu escopo estiver coletando dados que podem estar incompletos ou que seja necessário pesquisar e não exija todos os parâmetros de pesquisa concluídos para uma pesquisa, o código fará bom uso da referência, semelhante ao uso das propriedades de valor nulo int? longo?. Além disso, abstrair sua lógica de negócios da coleta de dados até a necessidade de injetá-la traz muitos benefícios de desempenho, semelhantes a instanciar um objeto e iniciá-lo em nulo. O Entity Framework utiliza muita reflexão e dinâmica, o que pode prejudicar o desempenho, e a necessidade de ter um modelo flexível que possa ser dimensionado conforme a demanda é fundamental para gerenciar o desempenho.
Para mim, isso sempre fazia mais sentido do que usar jargões de tecnologia sobrecarregados, como proxies, delegados, manipuladores e outros. Depois de atingir o terceiro ou quarto idioma de programação, pode ficar confuso com eles.
fonte
Do livro "ASP.NET MVC 5 com Bootstrap e Knockout.js"
fonte
No contexto do EF, marcar uma propriedade como virtual permite que o EF use carregamento lento para carregá-lo. Para que o carregamento lento funcione, o EF precisa criar um objeto proxy que substitua suas propriedades virtuais por uma implementação que carrega a entidade referenciada quando ela é acessada pela primeira vez. Se você não marcar a propriedade como virtual, o carregamento lento não funcionará com ela.
fonte
A palavra-chave virtual é usada para modificar um método, propriedade, indexador ou declaração de evento e permitir que ela seja substituída em uma classe derivada. Por exemplo, esse método pode ser substituído por qualquer classe que o herda:
fonte
Não podemos falar sobre membros virtuais sem nos referirmos ao polimorfismo . De fato, uma função, propriedade, indexador ou evento em uma classe base marcada como virtual permitirá a substituição de uma classe derivada.
Por padrão, os membros de uma classe não são virtuais e não podem ser marcados como modificadores estáticos, abstratos, privados ou de substituição.
Exemplo Vamos considerar o método ToString () no System.Object . Como esse método é membro de System.Object, é herdado em todas as classes e fornecerá os métodos ToString () para todos eles.
A saída do código anterior é:
Vamos considerar que queremos alterar o comportamento padrão dos métodos ToString () herdados de System.Object em nossa classe Company. Para atingir esse objetivo, basta usar a palavra-chave override para declarar outra implementação desse método.
Agora, quando um método virtual é chamado, o tempo de execução verifica se há um membro substituinte em sua classe derivada e o chama se presente. A saída do nosso aplicativo será então:
De fato, se você verificar a classe System.Object, verá que o método está marcado como virtual.
fonte