Curso Entity Framework - Atualizando um grafo de entidade usando o DBContext no modo desconectado - XXIII
Nesta aula vamos mostrar como atualizar um grafo de entidades (um conjunto de entidades ou objetos) no cenário desconectado usando o DBContext. (aula anterior) |
Chegou o Curso ASP .NET MVC 5 Vídeo Aulas (C#)
Atualizar um grafo de entidades com todas as novas entidades é uma tarefa complexa no cenário desconectado.
O problema na atualização de um grafo de entidades no cenário desconectado é que o contexto não conhece qual operação foi realizada do lado do cliente.
Na figura abaixo temos a representação desse fato onde o contexto não conhece o estado de cada entidade após uma operação ter sido realizada no cliente :
Precisamos identificar o estado de cada entidade no grafo de entidades antes de
chamar o método SaveChanges().
Existem diferentes padrões para
identificar o estado de uma entidade que precisamos considerar na concepção da
camada de dados do Entity Framework.
Padrões para identificar o estado de uma entidade no cenário desconectado
Existem diversas formas de identificar o estado de uma entidade em um cenário desconectado. Dentre elas citamos:
Usar a propriedade Primarykey (Id) de uma entidade
Usando a propriedade state no conjunto de entidades (entity set)
Nota: Você pode usar o seu próprio método para identificar o estado da entidade baseado na sua arquitetura.
1- Usando a propriedade Id (primary Key) de uma entidade
Você pode usar a chave primária - PrimaryKey (Id) de cada entidade para determina o seu estado. Porém, você tem que decidir qual das seguintes regras de arquitetura vai usar:
Cada tipo de entidade deve possuir uma propriedade Id (chave primária)
O valor padrão da propriedade Id deve ser 0
A seguir temos a figura que mostra como usar a propriedade Id para verificar o estado da entidades no cenário desconectado:
No cenário desconectado, o Contexto 2 não conhece o estado de cada entidade. Ele tem que determinar o estado da entidade padrão usando a propriedade PadraoId e o estado do Professor usando a propriedade ProfessorId.
Se os valores de PadraoId e ProfessorId forem iguais a zero, isso significa que elas são uma nova entidade e se o valor não for zero então significa que as entidade foram modificadas.
Na figura temos que Padrao, Professor 1 e Professor 2 possui um valor diferente de zero para a propriedade Id de forma que eles são marcados como Modified e Professor 3 possui o valor zero para o Id e assim ele é marcado como Added.
A seguir veremos o código que representa essa operação.
Atualizando um grafo de entidades aluno usando o Id
Vamos usar a solução criada na aula 22 - Entity Framework - Adicionando um grafo de entidade usando o DBContext no modo desconectado.
Abra a solução e no arquivo Program.cs e inclua o código abaixo neste arquivo:
static void Atualizando_GrafoEntidades()
{
Padrao PadraoDesconectado = null;
using (var contexto = new EscolaDBEntities())
{
//
contexto.Configuration.ProxyCreationEnabled = false;
//
PadraoDesconectado = contexto.Padraos.Where(s => s.PadraoId == 58).Include(s => s.Professores).FirstOrDefault<Padrao>();
}
// Atualiza a entidade Padrao no modo desconectado
PadraoDesconectado.PadraoNome = "Nome do Padrão editado e alterado";
// Atualiza a coleção Professores editando o primeiro o professor e depois incluindo um novo professor
PadraoDesconectado.Professores.ElementAt(0).ProfessorNome = "Nome do professor Alterado";
PadraoDesconectado.Professores.Add(new Professor() { ProfessorNome = "Novo Professor", PadraoId = PadraoDesconectado.PadraoId });
using (var novoContexto = new EscolaDBEntities())
{
//marca o padrao baseado no PadraoId
novoContexto.Entry(PadraoDesconectado).State = PadraoDesconectado.PadraoId == 0 ? EntityState.Added : EntityState.Modified;
//marca o Professor baseado no PadraodId
foreach (Professor tchr in PadraoDesconectado.Professores)
novoContexto.Entry(tchr).State = tchr.ProfessorId == 0 ? EntityState.Added : EntityState.Modified;
novoContexto.SaveChanges();
}
}
|
Vejamos quais as vantagens dessa abordagem:
E as desvantagens são:
2- Usando a propriedade State em cada entidade
Outra maneira de determinar o estado de uma entidade é ter uma propriedade State em cada tipo de entidade e definir o estado apropriado a partir do lado do cliente no modo desconectado. Dessa forma precisamos definir o estado da entidade como a propriedade State do objeto da entidade e chamar o método SaveChanges no novo Contexto.
Primeiro vamos criar uma
interface IEntityObjectState com uma propriedade
enum chamada EntityObjectState:
public enum EntityObjectState
{
Added,
Modified,
Deleted,
Unchanged
}
interface IEntityObjectState
{
EntityObjectState ObjectState { get; set; }
}
|
A seguir vamos implementar a
interface IEntityObjectSate em cada entidade.
Abaixo vemos um exemplo para as entidades Padrao e
Professor :
public partial class Padrao : IEntityObjectState
{
public Padrao()
{
this.Alunos = new HashSet<Aluno>();
this.Professores = new HashSet<Professor>();
}
public int PadraoId { get; set; }
public string PadraoNome { get; set; }
public string Descricao { get; set; }
public virtual ICollection<Aluno> Alunos { get; set; }
public virtual ICollection<Professor> Professores { get; set; }
[NotMapped]
public EntityObjectState ObjectState
{
get;
set;
}
}
public partial class Professor : IEntityObjectState
{
public Professor()
{
this.Cursos = new HashSet<Curso>();
}
public int ProfessorId { get; set; }
public string ProfessorNome { get; set; }
public Nullable<int> PadraoId { get; set; }
public virtual ICollection<Curso> Cursos { get; set; }
public virtual Padrao Padrao { get; set; }
[NotMapped]
public EntityObjectState ObjectState
{
get;
set;
}
}
|
Defina a propriedade State no modo desconectado do lado do cliente e defina o estado da entidade como definido por ObjectState antes de chamar SaveChanges :
static void Atualizando_GrafoEntidades_2()
{
Professor professorExistente = null;
using (var context = new EscolaDBEntities())
{
context.Configuration.ProxyCreationEnabled = false;
professorExistente = context.Professores.FirstOrDefault<Professor>();
}
Padrao PadraoDesconectado = new Padrao() { PadraoNome = "New Standard", ObjectState = EntityObjectState.Added };
professorExistente.ObjectState = EntityObjectState.Modified;
//adiciona um professor existente ao Padrao
PadraoDesconectado.Professores.Add(professorExistente);
//adiciona um novo Padrao
PadraoDesconectado.Professores.Add(new Professor() { ProfessorNome = "New teacher", PadraoId = PadraoDesconectado.PadraoId, ObjectState = EntityObjectState.Added });
//
using (var newContext = new EscolaDBEntities())
{
// verifica a propriedade ObjectState e marca o apropriedado EntityState
if (PadraoDesconectado.ObjectState == EntityObjectState.Added)
newContext.Entry(PadraoDesconectado).State = System.Data.Entity.EntityState.Added;
else if (PadraoDesconectado.ObjectState == EntityObjectState.Modified)
newContext.Entry(PadraoDesconectado).State = System.Data.Entity.EntityState.Modified;
else if (PadraoDesconectado.ObjectState == EntityObjectState.Deleted)
newContext.Entry(PadraoDesconectado).State = System.Data.Entity.EntityState.Deleted;
else
newContext.Entry(PadraoDesconectado).State = System.Data.Entity.EntityState.Unchanged;
//verifica a propriedade ObjectState de cada professor e marca o apropriedado EntityState
foreach (Professor tchr in PadraoDesconectado.Professores)
{
if (tchr.ObjectState == EntityObjectState.Added)
newContext.Entry(tchr).State = System.Data.Entity.EntityState.Added;
else if (tchr.ObjectState == EntityObjectState.Modified)
newContext.Entry(tchr).State = System.Data.Entity.EntityState.Modified;
else if (tchr.ObjectState == EntityObjectState.Deleted)
newContext.Entry(tchr).State = System.Data.Entity.EntityState.Deleted;
else
newContext.Entry(tchr).State = System.Data.Entity.EntityState.Unchanged;
}
//salva as mudanças
newContext.SaveChanges();
}
}
|
As vantagens dessa abordagem são:
Desvantagens:
Apresentando as duas abordagens avalie qual se ajusta melhor ao seu cenário e a utilize quando for preciso.
Na
próxima aula veremos a
concorrência no Entity Framework.
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências: