Fala pessoal! Acho que o texto acabou ficando meio grande, mas espero
que alguém tenha paciência de ler, hahaha.
Bom, queria a opinião de vocês sobre um cenário que acredito que muitos já devam ter enfrentado.
Na empresa que trabalho, existem vários sistemas legados e arquiteturas que dificultam a manutenção e reutilização do código. Um dos grandes problemas são várias classes que trabalham como um Active Record, com SQL espalhado em vários lugares. Após um certo trabalho, convenci o pessoal de que seria bom utilizarmos algum ORM nas nossas soluções, utilizando preferencialmente um padrão Repository e alguns conceitos e padrões mostrados no DDD para modelarmos o domínio da nossa aplicação (digo alguns conceitos justamente para não levantar aqui a discussão sobre o que é DDD ou não).
Bom, como foi mostrado na thread de uns dias atrás que tratava sobre Tiny Types, os frameworks de acesso a dados em geral não trabalham muito bem quando seu modelo possui muita Orientação a Objeto. Todos eles vão exigir algo, como construtores vazios, propriedades com get e set, etc. Apesar de “ferir” um pouco alguns conceitos que seriam importantes para o domínio, acho que no meu cenário é um preço justo a pagar pela facilidade na utilização de um ORM. Porém, nos meus testes utilizando o Entity Framework Code First especificamente, eu senti algumas limitações quando existe herança nos seus modelos.
O modelo simplificado do que estou trabalhando pode ser visto na imagem abaixo:

Basicamente, uma Reserva contém uma coleção de Itens, que por sua vez pode ser do tipo Hotel, Aéreo ou Receptivo. Um Item do Tipo Aéreo, por sua vez, contém uma coleção de Trechos. Os outros tipos de Item também teriam outras propriedades relacionadas, mas essa simplificação é suficiente para entender o problema.
Bom, tudo beleza até aqui e os mapeamos do Entity Framework funcionam tranquilamente. Porém, uma limitação do Framework é que eu não consigo com uma mesma consulta no banco obter o agregado inteiro na resposta, pois a Reserva possui referência a uma coleção do tipo genérico ReservaItem, o que faz com que na consulta o Entity Framework não tenha acesso por exemplo aos Trechos, do Item do tipo Aéreo. No meu cenário o agregado todo deve vir preenchido do BD. Lazy Loading não é uma opção legal pois faria com que eu realizasse um número muito maior de acessos no banco. Com essa modelagem uma saída seria fazer uma consulta que retornasse todos os Trechos de todos os itens presentes no retorno da primeira consulta, mas como as outras subclasses também teriam propriedades especificas, isso poderia começar a se tornar custoso demais de juntar via código.
Uma saída, para continuar usando o Entity Framework seria ao invés de herança, tratar o cenário utilizando composição. Fazendo isso teria o seguinte diagrama:

Agora, ao invés dos tipos específicos herdarem do tipo pai, um Item filho “possui” um Item genérico. Isso torna o modelo bem menos real e ainda faz com que a classe ReservaItem possua referências a todos os tipos filhos, fazendo com que em cada momento apenas uma dessas propriedade não seja nula, o que para mim é muito ruim. Por outro lado, o Entity Framework mapeia isso tranquilamente e funciona que é uma beleza.
Mas ai que está o problema... Será que esse é um preço bom a se pagar para usar um ORM? Alguém já passou por algo semelhante? Como vocês costumam trabalhar com herança e ORM’s? Existe algum outro ORM que trabalha melhor situações desse tipo?
Valeu pela paciência em lerem! Aceito críticas e outras recomendações sobre soluções a adotar ou estudar.
Abraços!
--