Estrutura da Entidade - Ciclo de Vida
Tempo de vida
O tempo de vida de um contexto começa quando a instância é criada e termina quando a instância é descartada ou coletada como lixo.
O tempo de vida do contexto é uma decisão muito importante a se tomar quando usamos ORMs.
O contexto está funcionando como um cache de entidade, o que significa que ele contém referências a todas as entidades carregadas que podem crescer muito rápido no consumo de memória e também pode causar vazamentos de memória.
No diagrama abaixo, você pode ver o nível superior do fluxo de trabalho de dados do aplicativo para o banco de dados por meio do Contexto e vice-versa.
Ciclo de Vida da Entidade
O Ciclo de Vida da Entidade descreve o processo no qual uma Entidade é criada, adicionada, modificada, excluída, etc. As entidades têm muitos estados durante seu tempo de vida. Antes de ver como recuperar o estado da entidade, vamos dar uma olhada no que é o estado da entidade. O estado é um enum do tipoSystem.Data.EntityState que declara os seguintes valores -
Added: A entidade é marcada como adicionada.
Deleted: A entidade está marcada como excluída.
Modified: A entidade foi modificada.
Unchanged: A entidade não foi modificada.
Detached: A entidade não é rastreada.
Mudanças de estado no ciclo de vida da entidade
Às vezes, o estado das entidades é definido automaticamente pelo contexto, mas também pode ser modificado manualmente pelo desenvolvedor. Embora todas as combinações de interruptores de um estado para outro sejam possíveis, algumas delas não têm sentido. Por exemplo,Added entidade para o Deleted estado, ou vice-versa.
Vamos discutir sobre os diferentes estados.
Estado inalterado
Quando uma entidade está inalterada, ela é vinculada ao contexto, mas não foi modificada.
Por padrão, uma entidade recuperada do banco de dados está neste estado.
Quando uma entidade é anexada ao contexto (com o método Attach), ela também está no estado Inalterado.
O contexto não pode rastrear alterações em objetos aos quais ele não faz referência, portanto, quando eles são anexados, ele assume que eles estão inalterados.
Estado Independente
Desanexado é o estado padrão de uma entidade recém-criada porque o contexto não pode rastrear a criação de qualquer objeto em seu código.
Isso é verdadeiro mesmo se você instanciar a entidade dentro de um bloco de uso do contexto.
Desanexado é até mesmo o estado das entidades recuperadas do banco de dados quando o rastreamento está desabilitado.
Quando uma entidade é desanexada, ela não é vinculada ao contexto, portanto, seu estado não é rastreado.
Ele pode ser descartado, modificado, usado em combinação com outras classes ou usado de qualquer outra forma que você possa precisar.
Como não há rastreamento de contexto, não tem significado para o Entity Framework.
Estado adicionado
Quando uma entidade está no estado Adicionado, você tem poucas opções. Na verdade, você só pode separá-lo do contexto.
Naturalmente, mesmo que você modifique alguma propriedade, o estado permanece Adicionado, porque movê-lo para Modificado, Inalterado ou Excluído não faz sentido.
É uma nova entidade e não tem correspondência com uma linha no banco de dados.
Este é um pré-requisito fundamental para estar em um desses estados (mas esta regra não é imposta pelo contexto).
Estado modificado
Quando uma entidade é modificada, isso significa que ela estava no estado Inalterado e então alguma propriedade foi alterada.
Depois que uma entidade entra no estado Modificado, ela pode passar para o estado Desanexado ou Excluído, mas não pode voltar ao estado Inalterado, mesmo se você restaurar manualmente os valores originais.
Ele nem pode ser alterado para Adicionado, a menos que você desanexe e adicione a entidade ao contexto, porque uma linha com este ID já existe no banco de dados e você obteria uma exceção de tempo de execução ao persisti-la.
Estado excluído
Uma entidade entra no estado Excluído porque foi Inalterado ou Modificado e, em seguida, o método DeleteObject foi usado.
Este é o estado mais restritivo, porque é inútil mudar deste estado para qualquer outro valor exceto Desanexado.
o usingse quiser que todos os recursos que o contexto controla sejam descartados no final do bloco. Quando você usa ousing , o compilador cria automaticamente um bloco try / finally e chama dispose no bloco finally.
using (var context = new UniContext()) {
var student = new Student {
LastName = "Khan",
FirstMidName = "Ali",
EnrollmentDate = DateTime.Parse("2005-09-01")
};
context.Students.Add(student);
context.SaveChanges();
}
Ao trabalhar com contexto de longa duração, considere o seguinte -
Conforme você carrega mais objetos e suas referências na memória, o consumo de memória do contexto pode aumentar rapidamente. Isso pode causar problemas de desempenho.
Lembre-se de descartar o contexto quando não for mais necessário.
Se uma exceção fizer com que o contexto fique em um estado irrecuperável, todo o aplicativo pode ser encerrado.
As chances de problemas relacionados à simultaneidade aumentam à medida que aumenta o intervalo entre o momento em que os dados são consultados e atualizados.
Ao trabalhar com aplicativos da Web, use uma instância de contexto por solicitação.
Ao trabalhar com Windows Presentation Foundation (WPF) ou Windows Forms, use uma instância de contexto por formulário. Isso permite que você use a funcionalidade de controle de alterações fornecida pelo contexto.
Regras de ouro
Web Applications
Agora é uma prática comum e recomendada que, para aplicativos da Web, o contexto seja usado por solicitação.
Em aplicativos da web, lidamos com solicitações que são muito curtas, mas contêm todas as transações do servidor; portanto, têm a duração adequada para o contexto viver.
Desktop Applications
Para aplicativos de desktop, como Win Forms / WPF, etc., o contexto é usado por formulário / caixa de diálogo / página.
Já que não queremos ter o contexto como um singleton para nosso aplicativo, iremos descartá-lo quando passarmos de um formulário para outro.
Dessa forma, ganharemos muitas das habilidades do contexto e não sofreremos as implicações de contextos de longa duração.