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:
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:
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:
Finalmente, outros projetos que estão também no forno são o Microsoft ASP.NET MVC Framework e o SubSonic.
ASP.NET MVC Preview 2 Ref.: http://www.microsoft.com/downloads/details.aspx?FamilyID=38CC4CF1-773A-47E1-8125-BA3369BF54A3&displaylang=en
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
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.
Nossa que post excelente, parabens...
estava com uma dúvida em relação ao ORM, uso iBatis ou LINQ?
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
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?
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...
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ó!
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/
Olá pessoal, tudo certo? Bom, se você tem acompanhado os posts e webcasts frequentes do Otávio , do Gebara
Olá pessoal, tudo certo? Para quem anda acompanhando a evolução do Entity Framework, componente importante
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
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:
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
// Representação das tabelas remotas do DataClass2
Table<Order> order = context.GetTable<Order>();
// Construindo a consulta LINQ.
where p.Age >= 40
select new {p.Name, p.Age, p.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
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 :)
[]s
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
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
Olá Manuel, tudo certo?
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:
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! :)
Olá pessoal, tudo certo? O último TechEd 2008 trouxe algumas novidades sobre o mundo ADO.NET Entity Framework
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?