direto ao ponto: efeitos colaterais de um orm no seu domínio
TRANSCRIPT
Direto ao ponto
Software em contexto
Os efeitos colaterais de um ORM no seu domínio
Entity Framework vs NHibernate
Agenda• Modelo de domínio e Persistence Ignorance• ORM, o que é?• Modelando um agregado
• Entidades• Objetos de valor
• Alterando uma entidade de um agregado• Considerações finais
Quem somos?Robson Castilho@nosborcastilho
Gustavo Fontes@GusFFontes
André Baltieri@andrebaltieri
José Roberto Araújo@jrobertofaraujo
Yan Justino@YanJustino
Modelo de domínio e Persistence Ignorance
• Uma abstração do problema de domínio• Contém a logica para resolver problemas do negocio• Não possui influencia de agentes externos
ORM – Object Ralational Mapping
• O que é?
Modelo de agragadoProgramação
IEnumerable<Sessao>SessoesPeriodoDeExibicao Exibicao
Sessao
Guid FilmeIdGuid SalaId
DateTime Databool EstaDisponivel
1..N
PeriodoDeExibicao
DateTime InicioDateTime Fim
Persistindo um agragado: Puro public sealed class Programacao : RaizDeAgregado {
public PeriodoDeExibicao Exibicao { get; private set; }
public IEnumerable<Sessao> Sessoes { get;}
public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { _sessoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }
Persistindo um agragado: NHibernate public class Programacao : RaizDeAgregado { public virtual EF.PeriodoDeExibicao Exibicao { get; protected set;}
public virtual IList<Sessao> Sessoes { get ;}
protected Programacao() { }
public Programacao(EF.PeriodoDeExibicao exibicao,List<Sessao> sessoes) { essoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); }
Persistindo um agragado: NHibernate public class Sessao : Entidade { public virtual Guid FilmeId { get; } public virtual Guid SalaId { get; }
public virtual DateTime Data { get; }
public virtual int IngressosVendidos { get; protected set; } public virtual bool Disponivel { get; protected set; }
protected Sessao() {
}
Mapeamento de entidade: NHibernate public class ProgramacaoMap : ClassMap<Programacao> { public ProgramacaoMap() { Id(p => p.Id);
Component(p => p.Exibicao, e => { e.Map(pe => pe.Inicio); e.Map(pe => pe.Fim);
});
HasMany(p => p.Sessoes) .KeyColumns .Add("ProgramacaoId")
.Cascade.AllDeleteOrphan() .Cascade.SaveUpdate();
Table("Programacao"); } }
Objeto de valor
Relacionamento com Entidade
Persistindo um agragado: Entity Framework public class Programacao : RaizDeAgregado {
public virtual ICollection<Sessao> Sessoes { get; private set; }
public PeriodoDeExibicao Exibicao { get; private set; }
private Programacao() { }
public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { Id = Guid.NewGuid(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }
Persistindo um agragado: Entity Framework public sealed class Sessao : Entidade { public Guid FilmeId { get; private set; } public Guid SalaId { get; private set; }
public Guid ProgramacaoId { get; private set; }
public DateTime Data { get; private set; } public int IngressosVendidos { get; private set; } public bool Disponivel { get; private set; }
private Sessao() {
}
Mapeamento de entidade: Entity Framework
public class ProgramacaoMap:EntityTypeConfiguration<Programacao> { public ProgramacaoMap() { HasKey(p => p.Id);
HasMany(p => p.Sessoes) .WithRequired() .HasForeignKey(_ => _.ProgramacaoId) .WillCascadeOnDelete(); ToTable(@"Programacao"); } }
public class PeriodoDeExibicaoMap:ComplexTypeConfiguration<PeriodoDeExibicao> { public PeriodoDeExibicaoMap() { Property(e => e.Inicio) .HasColumnName("Inicio") .HasColumnType("datetime");
Property(e => e.Fim) .HasColumnName("Fim") .HasColumnType("datetime"); } }
Alterando Agregado: Adicionando uma nova sessão com NH
public void Editar(Programacao programacao) { using (var tran = _session.BeginTransaction()) { _session.Update(programacao); tran.Commit(); }
}
public virtual void AdicionarSessao(Sessao sessao) { if (Exibicao.Disponivel()) _sessoes.Add(sessao); else throw new InvalidOperationException("Essa programação não está disponivel"); }
Alterando Agregado: Adicionando uma nova sessão com EF
public void AdicionarSessao(Sessao sessao) { if (Exibicao.Disponivel()) _Sessoes.Add(sessao); else throw new InvalidOperationException("Essa programação não está disponivel"); }
public void Editar(Programacao programacao) { _conexao.Entry<Programacao>(programacao).State = System.Data.Entity.EntityState.Modified; _conexao.SaveChanges(); }
Alterando Agregado: Removendo uma sessão com NH
public void Editar(Programacao programacao) { using (var tran = _session.BeginTransaction()) { _session.Update(programacao); tran.Commit(); }
}
public virtual void SessaoIndisponivel(Sessao sessao) { _sessoes.Remove(sessao); }
Alterando Agregado: Removendo uma sessão com EF
public void Editar(Programacao programacao) { _conexao.Entry<Programacao>(programacao).State = System.Data.Entity.EntityState.Modified; _conexao.SaveChanges(); }
public class SessaoMap:EntityTypeConfiguration<Sessao> { public SessaoMap() { HasKey(s => new { s.Id, s.ProgramacaoId }); } }
public void SessaoIndisponivel(Sessao sessao) { _Sessoes.Remove(sessao); }
Agregado: Trabalhando com listas somente leitura
public sealed class Programacao : RaizDeAgregado { private IList<Sessao> _sessoes;
public PeriodoDeExibicao Exibicao { get;}
public IEnumerable<Sessao> Sessoes { get { return _sessoes; } }
public Programacao(PeriodoDeExibicao exibicao,List<Sessao> sessoes) { _sessoes = new List<Sessao>(); Exibicao = exibicao; sessoes.ForEach(s => AdicionarSessao(s)); } }
Agregado: Trabalhando com listas somente leitura com NH
HasMany<Sessao>(Reveal.Member<Programacao>("Sessoes")) .KeyColumns .Add("ProgramacaoId") .Access.CamelCaseField(Prefix.Underscore) .Cascade.AllDeleteOrphan() .Cascade.SaveUpdate();
public class Programacao : RaizDeAgregado { private IList<Sessao> _sessoes;
public virtual EF.PeriodoDeExibicao Exibicao { get; }
public virtual IEnumerable<Sessao> Sessoes { get { return _sessoes; } }
Agregado: Trabalhando com listas somente leitura com EF public class Programacao : RaizDeAgregado { public static Expression<Func<Programacao, ICollection<Sessao>>> SessaoExpresson = f => f._Sessoes;
protected virtual ICollection<Sessao> _Sessoes { get; set; }
public IEnumerable<Sessao> Sessoes { get { return _Sessoes.ToList(); } }
}
HasMany(Programacao.SessaoExpresson) .WithRequired() .HasForeignKey(_ => _.ProgramacaoId) .WillCascadeOnDelete();
/SoftwareEmContexto
/softwareemcontexto
/softwareemcontexto
Nossos links
Referências• https://goo.gl/KUAttn• https://goo.gl/yB827x