Welcome to MSDN Blogs Sign in | Join | Help
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.

image

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.: http://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.: http://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.: http://www.microsoft.com/downloads/details.aspx?FamilyId=15DB9989-1621-444D-9B18-D1A04A21B519&displaylang=en

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.: http://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.: http://www.codeplex.com/subsonic

SubSonic: 2.1 Beta 2 Available Now
Ref.: http://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.

Posted: Wednesday, March 26, 2008 9:25 PM by wcamb
Filed under:

Comments

Acaz said:

Nossa que post excelente, parabens...

estava com uma dúvida em relação ao ORM, uso iBatis ou LINQ?

# March 28, 2008 1:30 PM

wcamb said:

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

Waldemir

# March 28, 2008 2:55 PM

Diogo Curto said:

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?

# April 3, 2008 2:04 PM

Acaz said:

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...

# April 3, 2008 2:33 PM

wcamb said:

Olá Acaz, tudo certo?

O importante é continuar acompanhando a evolução do ADO.NET Entity Framework, que já está em Beta 3.

De fato, trabalhar com o LINQ to SQL exigirá a instalação do .NET 3.0 + .NET 3.0 SP1 + .NET 3.5.

Mas tudo isso mantendo a compatibilidade com as aplicações em .NET 2.0, lembre-se disso.

Veja o link e trecho a seguir:

Deploying Microsoft .NET Framework Version 3.0

Ref.: http://msdn2.microsoft.com/en-us/library/aa480198.aspx

De onde temos:

"The Microsoft .NET Framework 3.0 is the new managed code programming model for Windows®. It combines the power of the .NET Framework version 2.0 with new technologies for building applications that have visually compelling user experiences, seamless communication across technology boundaries, and the ability to support a wide range of business processes. These new technologies are Windows Presentation Foundation, Windows Communication Foundation, Windows Workflow Foundation, and Windows CardSpace. The .NET Framework 3.0 is included as part of the Windows Vista™ operating system; you can install it or uninstall it using Windows Features Control Panel.

The .NET Framework 3.0 adds new technologies to the .NET Framework 2.0, which makes the .NET Framework 3.0 a superset of the .NET Framework 2.0. You can think of .NET Framework 3.0 as an "additive" release to the .NET Framework 2.0, as contrasted with a generational release where software is revised across the board. (For example, the .NET Framework 2.0 was a generational release over the .NET Framework 1.0.)

Because .NET Framework 3.0 is an additive release and uses the core run-time components from .NET Framework 2.0, it is completely backward compatible with the earlier version. Your existing .NET Framework 2.0 based-applications will continue to run without any modifications and you can safely continue your investments using the technologies that shipped with .NET Framework 2.0."

Por enquanto é só!

[]'s

Waldemir.

# April 3, 2008 7:33 PM

wcamb said:

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.

# April 3, 2008 7:42 PM

Arquitetura de Soluções said:

Olá pessoal, tudo certo? Bom, se você tem acompanhado os posts e webcasts frequentes do Otávio , do Gebara

# April 25, 2008 2:14 PM

Arquitetura de Soluções said:

Olá pessoal, tudo certo? Para quem anda acompanhando a evolução do Entity Framework, componente importante

# May 16, 2008 6:08 PM

Binhonew said:

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!

FABIANO

# May 30, 2008 7:26 AM

wcamb said:

Olá Fabiano, tudo certo?

Obrigado pelos comentários no blog!

Com certeza, discutir LINQ e EF é muito importante, assim como realizar bons testes e provas de conceito, para uma boa decisão de projeto.

Para suas perguntas, veja alguns comentários:

>> 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?

[wcamb] De fato não. É importante que no momento de geração de cada classe, você escolha as entidades que serão implementadas. Assim, cada entidade pode estar em dataclasses separadas, o que irá permitir um bom mapeamento de relacionamento e possíveis alterações das entidades. Um exemplo seria agrupar tabelas e relacionamentos afins em DataClasses específicas, eviando-se um mapeamento de todas as entidades numa única DataClasses.

>> O ADO.NET Entity Framework trabalha melhor isso?

[wcamb] Creio que a abordagem seria a mesma. Note que o LINQ to SQL não implementa uma camada de abstração, o que de fato muda a forma de instância e acesso aos objetos internos mapeados.

Como exemplo, pense num projeto LINQ TO SQL, onde usamos dois arquivos .DBML, um para cada DataClass mapeamento um grupo de objetos específicos. O acesso as tabelas ficaria assim:

static void Main(string[] args)

{

   // Contexto de acesso ao banco de dados.

   DataContext context = new DataContext("Data Source=.\\SQLEXPRESS;AttachDbFilename=C:\\Database\\petdb.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True");

   // Representação das tabelas remotas do DataClass1

   Table<People> people = context.GetTable<People>();

   // Representação das tabelas remotas do DataClass2

   Table<Order> order = context.GetTable<Order>();

   // Construindo a consulta LINQ.

   var query = from p in people

   where p.Age >= 40

   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);

   }

}

[wcamb] Ou seja, não tenho impacto de programação, uma vez que ambos os dataclasses estão no mesmo namespace, sobre o mesmo banco de dados:

[System.Data.Linq.Mapping.DatabaseAttribute(Name="petdb")]

public partial class DataClasses1DataContext : System.Data.Linq.DataContext

[System.Data.Linq.Mapping.DatabaseAttribute(Name="petdb")]

public partial class DataClasses2DataContext : System.Data.Linq.DataContext

[wcamb] Um ponto de impacto sim será na qualidade do seu modelo de dados. Nesse ponto, vale bons testes com diferentes complexidades de modelos para ver o comportamento. O blog do Dany Simons é uma boa referência sobre essa discussão, vou reler também :)

Ref.: http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx

>> Devo ter uma segunda camada de negocio ou juntar tudo nas classes geradas pelo linq.?

[wcamb] Minha sugestão é separar, isto é, deixar suas implementações de negócio em classes separadas das classes de mapeamento das entidades do LINQ to SQL. O mesmo vale quando estiver usando EF. Isso garante que, caso haja qualquer alteração ou update de mapeamento (e elas acontecerão), você não tenha surpresas como perda de customizações que tenha feito diretamente nos mapeamentos. Na verdade, mesmo essas customizações eu recomendo ter cuidado.

>> Qual seria a melhor estrutura visando um reaproveitamento legal e performance?

[wcamb] Quando a performance, recomendo ver o artigo a seguir:

Ref.: http://visualstudiomagazine.com/features/article.aspx?editorialsid=2372

[wcamb] Quanto ao reaproveitamento, creio que manter a simples separação entre customizações de negócio e classes de mapeamento já seja uma boa abordagem. Mas ainda pretendo consolidar um material melhor sobre melhores práticas para projetos LINQ e EF. Aguarde!

>> não sei se consegui ser claro!

[wcamb] conseguiu sim. Em linhas gerais, como manter o mapeamento de entidades do modelo de dados no projeto usando LINQ to SQL ou EF e quais seriam boas práticas de reuso e performance. São perguntas muito pertinentes.

>> mais acho que esse duvida que tambem e acompanhada de um pouco de falta de conhecimento pode gerar uma palta legal.

[wcamb] acompanhar os blogs indicados e bons exemplos é um bom caminho, pois a comunidade tem participado ativamente com dicas e questões semelhantes. Por isso, sejam benvindas as perguntas :)

Por enquanto é só!

[]s

Waldemir.

# May 30, 2008 6:49 PM

Binhonew said:

Olá waldemir.

Muito obrigado pelas dicas foram bem esclarecedoras...

O que acho mais interessante neste novo modelo e que ganhamos muito com tempo de dev! aproveitando tudo direitinho teremos um grande resultado no final do projeto.

Muito Obrigado pelos esclarecimentos...

Abraço

Fabiano

# June 2, 2008 9:06 AM

sacramento said:

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 Sacramento

# June 4, 2008 5:04 PM

wcamb said:

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.

# June 4, 2008 7:11 PM

Arquitetura de Soluções said:

Olá pessoal, tudo certo? O último TechEd 2008 trouxe algumas novidades sobre o mundo ADO.NET Entity Framework

# June 14, 2008 2:40 PM

Funny said:

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?

# October 10, 2008 11:39 AM

wcamb said:

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.

# October 13, 2008 1:32 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

  
Enter Code Here: Required

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker