Revisitando a Persistência - ORM, ADO.NET Entity Framework, Data Services, Sync, LINQ e ainda outros comentários.
Olá pessoal, tudo certo?
No último post, começamos uma discussão interessante sobre persistência. Vamos rever alguns pontos e avançar mais um pouquinho. A motivação do estudo é uma só: como e por que integrar a modelagem e programação Orientada a Objetos com Bancos de Dados Relacional?
De fato, a maior parte de nossas aplicações usam um banco relacional para armazenamento de dados. Como vimos, essa tecnologia é vigente no mercado, por sua maturidade, fundamentação em uma teoria matemática forte (baseada em conjuntos) e padronização. Veja que, quando usamos o modelo relacional, o objetivo é a normalização e a otimização de recursos no armazenamento de nossos dados ou coleções;
Da mesma forma, a maior parte de nossas aplicações usam linguagens de programação orientada a objetos em seu desenvolvimento. Com isso, nosso objetivo é a modelagem de processos, como a definição de comportamentos e tipos de entidades na forma de classes;
Surge assim um problema chamado "Impedance Mismatch" , que é a dificuldade em realizar o mapeamento entre os dois mundos, o mundo relacional e o mundo OO.
Para esse problema, uma solução é o uso de uma camada de tradução ou ORM - Object Relational Mapping, que é responsável por esse mapeamento entre o mundo OO e o mundo relacional. Pense que o grande desejo é que essa camada de mapeamento ORM seja transparente para nossas aplicações.
Existe uma série de ferramentas no mercado que oferecem soluções implementando camadas ORM e seus recursos. Veja que a técnica de mapeamento objeto-relacional ainda precisa resolver alguns problemas de mapeamento e representação de dados entre ambos os mundos, problemas como:
- Mapeamento entre Entidade e Classe (queries X tipos)
- Herança
- Tratamento de Chaves (primárias, extrangeiras)
- Representação de Relacionamentos
- Campos Calculados
- Diferenças entre tipos SQL e linguagens de programação
- Locking e Isolation Level
- Tunning
- Caching, entre outros.
De fato, existe um impacto em banco de dados durante a implementação desses modelos ORM. Para a implementação de herança, por exemplo, temos técnicas de mapeamento horizontal, mapeamento vertical, mapeamento filtrado, que implementam abordagens diferentes para a representação da herança entre classes, através de 1 ou mais tabelas em banco.
No final, a própria decisão pelo uso de uma camada de mapeamento objeto-relacional deve ser ponderada em função de um conjunto de critérios (pessoais), como:
- Desempenho final exigido (SLA envolvido na solução);
- Frequência de Leitura x Escrita x Atualização;
- Flexibilidade e Custo de Manutenção;
- Desempenho e Redundância x Custo de Manutenção e Formas Normais;
- Consumo de Espaço x Desempenho;
- Tempo de Processamento de Consultas;
- Estilo da Aplicação;
- Integração com sistemas legados, etc.
Atualmente, temos uma série de novos frameworks disponíveis para o tratamento de acesso a dados, assim como para a construção de consultas integradas ao modelo orientado a objetos. É o caso do próprio ADO.NET Entity Framework e do LINQ, como citamos anteriormente. Porém, já existem muito outros componentes disponíveis, que você precisa conhecer. Para ajudar um pouco nesse roadmap, segue um conjunto de links interessante:
ADO.NET 2.0
Nosso ADO.NET clássico, onde encontramos as estruturas Dataset, DataReader, Datatable, DataAdapter, DbConnection, DbCommand, etc.
Ref.: https://msdn2.microsoft.com/en-us/data/aa937722.aspx
ADO.NET 3.5
Disponível com o .NET Framework 3.5, onde encontramos as versões de LINQ to Objects, LINQ to DataSets, LINQ to SQL, LINQ to XML, enfim, as implementações de LINQ - Language Integrated Quey, que permite a construção de consultas integradas ao modelo OO, para o acesso aos dados no mundo relacional ou ainda qualquer outra fonte de dados, como arquivos XML, estruturas customizadas, etc. Em linhas gerais, LINQ implementa um conjunto de mecanismos e bibliotecas para consultas de dados em memória, através de coleções.
Ref.: https://www.microsoft.com/downloads/details.aspx?FamilyID=333325fd-ae52-4e35-b531-508d977d32a6&DisplayLang=en
ADO.NET vNext
A próxima versão do ADO.NET deve encapsular um conjunto de novas ferramentas, que já estão sendo disponibilizadas em CTP e Previews para nossa discussão e alegria. Os principais componentes que já temos são:
- ADO.NET Entity Framework Beta 3
Responsável pelo mapeamento objeto-relacional, através do chamado EDM - Entity Data Model. Esse modelo permite o mapeamento de classe objeto em qualquer tipo de fonte de dados (não só o modelo relacional) através de um processo de tradução implementado em 3 camadas: camada conceitual, camada lógica e camada de mapeamento. A documentação que acompanha o pacote está muito boa, vale conferir.
Ref.: https://www.microsoft.com/downloads/details.aspx?FamilyId=15DB9989-1621-444D-9B18-D1A04A21B519&displaylang=en
ADO.NET Data Services (codenome “Astoria”) => download do ASP.NET 3.5 Extensions Preview, onde temos o ASP.NET 3.5 + ADO.NET Data Services.
Permiti a publicação e navegação das informações de um banco de dados de forma online.
Ref.: https://www.microsoft.com/downloads/details.aspx?FamilyId=A9C6BC06-B894-4B11-8300-35BD2F8FC908&displaylang=enUm exemplo muito interessante de navegação via Data Services você encontra aqui.Veja que nosso velho Northwind agora pode ser navegado diretamente através de querystrings, praticamente. As aplicações são inúmeras, como integrações para aplicações AJAX, consumo via WCF, aplicações Web convencionais, etc.
Northwind - Navegando dados online via ADO.NET Data Services
Ref.: https://astoria.mslivelabs.com/OnlineServiceNorthwind.aspx
ADO.NET Sync Services v1.0
Sync Services é uma primeira parte de um framework ainda em desenvolvimento, que deve atender as aplicações que ficam parcialmente conectadas, ou seja, que demandam o uso de um cache local em tempos de desconexão, com a necessidade de uma sincronização de dados posterior com o servidor. Esses mecanismos e estruturas de persistências temporárias são o objetivo do Sync Services.Recomendo assistir um vídeo do channel9, nesse link:
Ref.: https://channel9.msdn.com/Showpost.aspx?postid=384948Para saber ainda mais, acompanhe as discussões aqui:
Ref.: https://www.danielmoth.com/Blog/2008/02/adonet-sync-services.htmlRef.: https://www.microsoft.com/downloads/details.aspx?FamilyId=75FEF59F-1B5E-49BC-A21A-9EF4F34DE6FC&displaylang=en (sync for devices)
Ref.: https://www.microsoft.com/downloads/details.aspx?&FamilyID=7849b34f-67ab-481f-a5a5-4990597b0297&DisplayLang=en (sync for desktop)
Finalmente, outros projetos que estão também no forno são o Microsoft ASP.NET MVC Framework e o SubSonic.
- O Microsoft ASP.NET MVC Framework habilita o desenvolvimento de aplicações Web no modelo MVC - Model View Controller. Nesse modelo, a lógica da página fica na porção CONTROLLER, os objetos de HTML ficam no módulo VIEW e a lógica da aplicação fica na porção MODEL. Não está muito relacionado com o acesso a dados, mas colabora! :)
ASP.NET MVC Preview 2
Ref.: https://www.microsoft.com/downloads/details.aspx?FamilyID=38CC4CF1-773A-47E1-8125-BA3369BF54A3&displaylang=en
- O SubSonic Project, conduzido por Rob Conery, é um conjunto de ferramentas que deve gerar de forma completa a camada de acesso a dados. Ao contrário do modelo ORM, onde temos o mapeamento do mundo OO no mundo relacional, SubSonic será um gerador de código ou do modelo de classes OO, a partir do schema do banco relacional. Bonito! :)
Para saber mais, acompanhe as discussões no Codeplex, aqui:
SubSonic Codeplex
Ref.: https://www.codeplex.com/subsonicSubSonic: 2.1 Beta 2 Available Now
Ref.: https://www.codeplex.com/subsonic/Release/ProjectReleases.aspx?ReleaseId=5636
Enfim, Vida Longa ao Blog!!!
Acho que não vai faltar assunto para os próximos meses, não acham?
Por enquanto é só! Até o próximo post e boa leitura a todos... :)
Waldemir.
Comments
Anonymous
March 28, 2008
Nossa que post excelente, parabens... estava com uma dúvida em relação ao ORM, uso iBatis ou LINQ?Anonymous
March 28, 2008
Olá Acaz, tudo certo? Obrigado pelos comentários! :) De fato, iBATIS e HIBERNATE são frameworks de persistência que oferecem versões para o mundo .NET. Nascido no mundo Java, o iBATIS tem a versão iBATIS.NET, assim como o HIBERNATE tem a versão NHIBERNATE. Se sua aplicação está no mundo .NET, LINQ torna-se agora uma nova alternativa para sua implementação na camada de persistência, fazendo esse mapeamento objeto-relacional (ORM). O que recomendo de fato é que você faça testes, que experimente as tecnologias. Pessoalmente, aposto na dupla LINQ + ADO.NET Entity Framework, devido sua natureza flexível quanto ao uso de múltiplos bancos ou múltiplas fontes de dados. Se o cenário envolve o uso de Microsoft SQL Server, o LINQ se torna ainda mais atraente, pois através de uma única classe LINQ TO SQL, você fará o mapeamento de tabelas no mundo OO, sem mesmo a necessidade do ADO.NET Entity Framework. Veja um exemplo de LINQ TO SQL a seguir: ////////////////////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.Linq; namespace LINQtoSQL { class Program { static void Main(string[] args) { // Contexto de acesso ao banco de dados. DataContext context = new DataContext("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\LINQtoSQL\petdb.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"); // Representação das tabela remota People. Table<People> people = context.GetTable<People>(); // Construindo a consulta LINQtoSQL. var query = from p in people where p.Age >= 30 select new { p.Name, p.Age, p.CanCode }; // Executando a consulta LINQ. foreach(var item in query) { Console.WriteLine("Name: {0} - Age: {1} - CanCode: {2}", item.Name, item.Age, item.CanCode); } } } } ////////////////////////////////////////////////////////////////////////////////////// O exemplo acima faz uma consulta ao banco petdb.mdf, onde a tabela People é percorrida via LINQ. Para saber mais, veja o link... LINQ to SQL Ref.: http://msdn2.microsoft.com/en-us/library/bb386976.aspx Depois me conta o que você decidiu! :) []'s WaldemirAnonymous
April 03, 2008
Waldemir, Pelo que eu consegui entender, o subsonic consegue se entender fácilmente com o Entity e o LINQ. Mas fiquei com uma pulga a trás da orelha, não existem sombreamentos nos 3 projetos? Não seria melhor um framework-integrado?Anonymous
April 03, 2008
Olá waldemir, ainda não fiz os testes, mas eu estou com o framework 2.0 no momento, vou construir um projeto agora, e por enquanto nao posso usar 3.5, vou utilizar ele com o iBatis...Anonymous
April 03, 2008
The comment has been removedAnonymous
April 03, 2008
Olá Diogo, tudo certo? Obrigado pelos comentários. De fato, lembre-se que tudo está ainda em desenvolvimento, alguns em Beta, outros em CTP e outros em CodePlex. Ou seja, muito espaço para direcionamento e sugestões. E ainda: o Data Services, o Entity Framework e o Sync estão sob o mesmo projeto, o ADO.NET vNext. Creio que ainda veremos alguns alinhamentos nesses frameworks. Vale acompanhar o blog do time de ADO.NET, com certeza:) ADO.NET team blog Ref.: http://blogs.msdn.com/adonet/ []'s Waldemir.Anonymous
April 25, 2008
Olá pessoal, tudo certo? Bom, se você tem acompanhado os posts e webcasts frequentes do Otávio , do GebaraAnonymous
May 16, 2008
Olá pessoal, tudo certo? Para quem anda acompanhando a evolução do Entity Framework, componente importanteAnonymous
May 29, 2008
Olá waldemir, Estou atualmente arquitetando uma solução, venho das versões 1.1 e 2.0 e ja estava acostumado a trabalhar com 3 camadas ter minhas classes de acesso a dados e negocio bem definidas e isso sempre funcionou bem! tenho estudado bastante o linq e agora o ADO.NET Entity Framework mais tenho uma duvida cruel! e gostaria de abrir uma discussão sobre o assunto. Seguinte a ideia e criar uma framework onde poderamos ter um grande numero de reaproveitamento de processos em varios projetos, antigamente eu teria esse projeto separado com suas entidades que não seriam um reflexo ideal da tabela mais bem proximos e ele seria adicionado nos outros projetos e reaproveitado. Agora com o linq e outros muda totalmente o conceito! eu estou aprendendo a pensar diferente e isso esta um pouco complicado. As duvidas: Utilizando o Linq to SQL ele gera os objetos automaticos a duvida é, não terei uma classe gigante que se tornará lenta e muito grande ao longo do tempo? O ADO.NET Entity Framework trabalha melhor isso? Devo ter uma segunda camada de negocio ou juntar tudo nas classes geradas pelo linq.? Qual seria a melhor estrutura visando um reaproveitamento legal e performance? não sei se consegui ser claro! mais acho que esse duvida que tambem e acompanhada de um pouco de falta de conhecimento pode gerar uma palta legal. OBRIGADO! FABIANOAnonymous
May 30, 2008
The comment has been removedAnonymous
June 02, 2008
The comment has been removedAnonymous
June 04, 2008
Olá Waldimir: Estive a ver o código que postou e como estou a iniciar-me no LINQ gostaria de saber se poderia ajudar no seguinte: A maior parte dos videos e msdn disponíveis na net utilizam o server explorer usando sempre o wizard para relacionar a base de dados e usar o LINQ...de facto muito fácil,só que no meu caso eu preciso aceder a várias bases de dados com nomes diferentes,ou seja não se trata de uma única base de dados,portanto penso que terei que seguir por outro caminho...aquilo que eu pretendia era abrir a base de dados(access) através do ADO.NET e usá-la no LINQ...Usei o seu código mas parece-me que falta algo não? Fico agradecido MAnuel SacramentoAnonymous
June 04, 2008
Olá Manuel, tudo certo? Obrigado pelos comentários no blog! Sem dúvida, meu exemplo foi simple e ainda baseado apenas em LINQ TO SQL. De fato, utilizei o Server Explorer para uma conexão com um banco .mdf local. Assim, meu DataContext ficou apontado para o arquivo exemplo, como abaixo: // Contexto de acesso ao banco de dados. DataContext context = new DataContext("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Demo_LINQtoSQL\petdb.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True"); Para cenários de acesso remoto, vale utilizar uma variável para ConnectionString em arquivo de configuração ou em serviço que seja consultado para devolver a string desejada e permitida: Vejamos um exemplo: no arquivo Web.config ou App.config da aplicação, podemos ter a connectionString de necessária. No exemplo abaixo, tenho a string "myConnectionString". <connectionStrings> <add name="myConnectionString" connectionString="Data Source=.sqlexpress;Initial Catalog=MyDataBase;Integrated Security=True" providerName="System.Data.SqlClient"/> </connectionStrings> Com essa string, fazemos a conexão ao banco desejado, conforme abaixo: Public Sub DataAccess() Dim objConnectionStringSettings As ConnectionStringSettings = ConfigurationManager.ConnectionStrings("myConnectionString") strConnectionString = objConnectionStringSettings.ConnectionString Dim cnn As New SqlConnection() cnn.ConnectionString = strConnectionString End Sub ou em C#... public DataAccess() { SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["myConnectionString"].ToString()); } A partir desta conexão, podemos criar as instâncias de tabelas e stored procs que serão consumidas e navegadas através de LINQ. Alguns exemplos interessantes você ainda encontra aqui: http://www.dotnetjunkies.ddj.com/QuickStartv20/aspnet/doc/management/retrieve.aspx#connectionstrings Depois diga-me se ajudou! :) []s Waldemir.Anonymous
June 14, 2008
Olá pessoal, tudo certo? O último TechEd 2008 trouxe algumas novidades sobre o mundo ADO.NET Entity FrameworkAnonymous
October 10, 2008
Estou utilizando LINQ para a camada de persistência. O LINQ gera os DTOs (Model) e os DataContexts (DAL) para mim. Porém, como faço para que na camada view do meu site, eu não utilize referência ao LINQ visto que preciso setar as informações no DTO e passá-lo para a BLL? Se eu criar um DTO meu de camada view, eu terei que na BLL converter este DTO para o DTO do LINQ, o que acaba sendo custoso no desenvolvimento para setar cada propriedade de um para o outro. Se eu utilizasse apenas um DTO (do LINQ), não teria mais esse trabalho de jogar os dados de um objeto para outro... Qual seria a melhor solução?Anonymous
October 13, 2008
Olá Funny, Obrigado pelos comentários no blog. Existem duas opções aqui: >> ou aplicamos o modelo IPOCO - Interface Plain Old CSharp Object do Entity Framework (se estivemos usando LINQ TO ENTITY + ADO.NET Entity Framework). Veja as discussões abaixo: Ref.: http://www.sitechno.com/Blog/IntroducingEntityFrameworkContribEasyIPocoImplementationV01.aspx Ref.: http://blogs.msdn.com/dsimmons/archive/2007/06/02/persistence-ignorance-ok-i-think-i-get-it-now.aspx >> ou sendo uma solução Web, avaliamos o ASP.NET Dynamic Data, que permite essa integração de forma direta, veja: Ref.: http://davidhayden.com/blog/dave/archive/2008/04/19/ASPNETDynamicDataWizardGeneratingLINQToSQLDataModelCustomPages.aspx Ref.: http://weblogs.asp.net/scottguportuguese/archive/2008/04/10/preview-do-asp-net-dynamic-data-dados-dinamicos-asp-net-disponivel.aspx Espero que ajude! Waldemir.