Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de Usuários
»Células Acadêmicas«
intcontpiada : 118
O melhor teclado da microsoft
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
Faça um pequeno teste com 10 questões de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programação com nosso treinamento on-line de lógica de programação
.:.
Veja nosso calendário de treinamentos
Gostou da Página?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 








Criando Uma Camada de Dados em .NET

Baixe os fontes aqui

Mesmo antes do .NET sempre buscamos utilizar a orientação a objetos e organizar o código de forma a evitar redundância de código. Não apenas pela questão da reutilização de código, mas por questões de manutenção, pois ao fazer manutenção do código passamos a ter toda a lógica centralizada, sem redundâncias.

Um tipo de código que tem muita tendência a ser repetitivo é o código de acesso a banco. Para evitar a repetição deste código cria-se camadas de acesso a dados isolando o código de acesso a dados do código da camada de regras de negócio.

Nos sistemas que desenvolvi em VB 6 e ASP 3 montei uma camada de dados bem versátil e a utilizei em vários sistemas. Quando passei a desenvolver com .NET criei uma camada de dados semelhante para utilização em sistemas .NET .

Em .NET, porém, devido a termos 100% da orientação a objetos, existe muita flexibilidade para a montagem da camada de dados. Assim sendo a forma que tenho utilizado é apenas uma das muitas possíveis para a montarmos esta camada de dados e tenho visto muitas implementações diferentes da camada de dados.

Então a idéia deste artigo é descrever a implementação que tenho utilizado para a camada de dados e porque optei por esta implementação, iniciando assim um bom debate no grupo de usuários devASPNet a respeito dos prós e contras de cada metodologia.

Primeiramente, antes de entrarmos nas características desta camada, vamos estabelecer alguns padrões para esta camada.

Toda a comunicação com o servidor de dados deve ser feita através de stored procedures.

Esse é um tema controverso, com certeza, mas foi isso que assumi como padrão no meu desenvolvimento.

Esse padrão vai de encontro a um oposto que alguns tem utilizado : Utilizar apenas SQL Ansi realizando todo o processamento na camada de negócios.

Então fica a pergunta : Em que casos utilizar um padrão e em que casos utilizar outro padrão ?

Stored Procedures

A favor

Qualquer instrução desenvolvida em stored procedures tem melhor performance do que a mesma instrução gerada via aplicação. Isso é característica dos servidores de dados, que utilizam cache e pré-compilação para garantir isso.

Fica mais simples dar manutenção em regras de acesso a dados quando estas estão em stored procedures, deixando o banco de dados mais flexivel.

Contra

Ao migrar de servidor de banco todas as stored procedures precisarão ser reconstruidas.

SQL ANSI

A favor

Independencia de servidor de dados

Contra

Menor aproveitamento dos recursos do servidor de dados

Independencia do servidor ou aproveitamento de recursos ?

É essa a questão que precisa ser respondida. Em minha opinião, na maioria dos casos já foi feito um grande investimento no servidor de banco de dados. Torna-se então interessante maximizar os resultados deste investimento, utilizando recursos específicos do servidor de dados, utilizando assim as stored procedures.

Porém quando estivermos desenvolvendo produtos para comercialização que precisarão falar com diversos bancos precisaremos da independencia de banco, precisaremos então do SQL Ansi.

Porém :

  • Produzindo softwares para comercialização, seria uma vantagem anuncia-los informando que são capazes de aproveitar o máximo do investimento feito em banco de dados pelo cliente. Desta forma seria interessante se a camada de dados fosse realmente re-criada para vários bancos.
  • Existem alguns ambientes de produção que necessitam realmente que a camada de dados tire o máximo de proveito do investimento em banco. Já vi ambientes assim em que uma softwarehouse optou por reproduzir a camada de dados sempre que necessário.
  • Ao contrário do que se imagina, mesmo com essa arquitetura consegue-se utilizar bancos que não utilizam stored procedures, tal como MySQL. Para esses casos torna-se necessária uma tradução dos nomes das procedures para instruções de banco na camada de dados.

Desta forma opto por fazer sempre o uso de stored procedures, sabendo que em muitos casos de construção de produtos para comercialização valerá mais a pena utilizar SQL ANSI.

 

Troca de dados entre as camadas

Existe muita polêmica sobre como a troca de dados entre camadas deve ser realizada. Alguns gostam de realizar tal troca com dataSets, outros com objetos personalizados.

Os dataSets são um pouco mais pesados do que a criação de objetos personalizados. Porém os dataSets já possuem todo um mecanismo de controle de atualizações dos registros para quando isto for necessário - e frequentemente é.

Não ha uma resposta definitiva a este ponto. Uma questão importante, porém, é destacar o que não fazer : Não utilize dataReaders para a troca de dados. O dataReader exige que a conexão com o banco se mantenha aberta, então se ele é utilizado para troca de dados a conexão ficará aberta bem mais tempo do que o necessário, gerando perda de escalabilidade.

Nos componentes que montei costumo utilizar o dataSet para entregar dados para o client, mas utilizar coleções mais simples para passar parâmetros para componentes.

Independencia de banco

Muitas vezes ao montar uma camada de acesso a dados temos que tomar uma difícil decisão : Devemos utilizar alguma camada intermediária de acesso a dados, tal como ODBC ou OLEDB e desta forma simplificar uma futura troca de banco ou devemos utilizar metodologias de acesso direto a nosso servidor para assim ganharmos performance ?

A novidade do .NET é que essa decisão não precisa ser tomada : Podemos ter as duas coisas. O .NET possui uma arquitetura de objetos que nos permite acessar bases de dados com providers específicos de cada base - e desta forma muito mais rápidos - e ainda assim conseguir trocar facilmente de base com uma simples reconfiguração.

Começando : A camada de objetos de banco

O primeiro passo é montarmos o componente que nos permitirá ter a independencia de banco ao mesmo tempo em que garantimos o máximo em performance, utilizando os providers específicos de cada banco.

Isso é possível através do uso de interface. As classes que fazem parte de um Data Provider no .NET estão implementadas com base em interfaces. Por exemplo, as classes de conexão (OLEDBCONNECTION, OraConnection, etc,) são todas baseadas na interface IDBConnection.

O fato de todas as classes estarem vinculadas a interfaces comuns permite que os componentes da aplicação apenas façam referência as interfaces e não as classes. Com isso os componentes podem utilizar uma classe connection sem saber exatamente a que Data Provider pertence, apenas utilizando as definições de métodos existentes na interface.

Porém o momento de criação da instância das classes é um momento em que a classe em si precisará ser conhecida. Deverá haver uma inteligência que decida que data provider utilizar com base em alguma configuração. Devemos então centralizar esta inteligência em um único componente. Precisamos criar um componente que seja o responsável por criar objetos de acesso a dados (os objetos de um data provider) e só esse componente saberá qual data provider estamos utilizando.

Esta classe em questão (vamos chama-la de objetosBanco) terá os seguintes métodos :

CriarConexao
CriarCommand
CriarAdapter

Além destes métodos básicos precisaremos de 2 adicionais para simplificar mais o desenvolvimento :

CriarObjetosBanco : Este método simplifica a criação dos objetos de banco, executando a sequencia de criação de uma conexão, um command e um adapter.

ObterParametros : Este método é utilizado para derivação de parâmetros, recurso fundamental para a montagem da camada de dados.

Derivação de parâmetros

Quando chamamos stored procedures precisamos saber exatamente quais parametros estas stored procedures irão receber. Se guardarmos esta informação no código então sempre que ocorrer uma alteração nas stored procedures torna-se necessário alterar também o código da camada de dados. A alternativa é realizarmos uma consulta a banco para descobrirmos qual a configuração de parâmetros da procedure. Isso torna a chamada da procedure mais dinâmica porém consome uma consulta a mais ao banco.

Este é o dilema da derivação de parâmetros : ganharmos consideravelmente na manutenção da aplicação sacrificando um pouco a performance.

É importante observar que sem a derivação de parâmetros seriamos obrigados a criar, na camada de acesso a dados, um componente para cada componente de negócio, uma espécie de mapeamento completo da base de dados. Utilizando a derivação de parâmetros evitamos isso.

Por isso na arquitetura que estarei demonstrando aqui estarei optando pelo uso da derivação de parâmetros.

Inicializando a classe

Quando a classe objetosBanco for instanciada ela precisará de imediato descobrir com qual provider ela deve trabalhar, checando as configurações do ambiente.

Para fazer isso devemos programar o constructor da classe, a sub new. Veja o código :

    'Abaixo encontra-se a variável e o enum que determinam

    'o tipo de banco

    Dim iBanco As eTipoBanco

     Public Enum eTipoBanco
        OLEDB = 1
        SQL = 2
    End Enum

    'Variável contendo a string de conexao

    Dim cString As String

     'o constructor da classe faz a leitura do tipo de banco

    Public Sub New()

        Dim app As New System.Configuration.AppSettingsReader

        iBanco = app.GetValue("tipobanco", GetType(Integer))

        cString = app.GetValue("StringConexao", GetType(String))

    End Sub

Utilizando a classe AppSettingsReader fazemos a leitura de configurações do manifesto da aplicação. A aplicação apenas precisará ter um manifesto que contenha as configurações tipobanco (o tipo do provider utilizado) e StringConexao (a string de conexão para o banco de dados.

Precisaremos também de variáveis para guardar os objetos de acesso a banco e podemos utilizar um enum para simplificar o trabalho de escolha do provider. Veja como fica :

    Dim cn As IDbConnection
    Dim cmd As IDbCommand
    Dim da As IDataAdapter

Observe que as variáveis para conter os objetos de banco foram definidas como sendo de uma interface Vejamos como fica o código de criação do objeto Command e do objeto Connection :

    <Description("Gera uma conexão conforme configuração do manifesto")> _

    Public Function CriarConexao() As IDbConnection

        Select Case iBanco
            Case eTipoBanco.OLEDB
                Dim obj As New OleDb.OleDbConnection
                obj.ConnectionString = cString}
                Return (obj)
            Case eTipoBanco.SQL
                Dim obj As New SqlClient.SqlConnection
                obj.ConnectionString = cString
                Return (obj)
            Case Else
                Throw New ApplicationException("Erro de configuração na configuração do tipo de banco")

       End Select

     End Function

 

    <Description("Gera um command conforme configuração do manifesto")> _

    Public Function CriarCommand() As IDbCommand
        Select Case iBanco
            Case eTipoBanco.OLEDB
                Return (New OleDb.OleDbCommand)
            Case eTipoBanco.SQL
                Return (New SqlClient.SqlCommand)
            Case Else
                Throw New ApplicationException("Erro de configuração na configuração do tipo de banco")

        End Select
    End Function

A variável iBanco recebeu seu valor no constructor da classe. Nas subs de criação dos objetos fazemos um select case para descobrir qual a configuração e criamos o objeto de banco adequado. Poderiamos utilizar Reflections para deixar o componente ainda mais versátil, mas para o exemplo neste formato já é adequado.

Os objetos criados serão guardados internamente nesta classe e disponibilizados para quem desejar fazer o acesso a banco. Por isso o método de criação de um dataAdapter tem uma variação a mais : Quem utilizar este componente poderá desejar criar o Adapter já vinculado ao command que encontra-se na classe ou não, criar o adapter para outro objetivo qualquer. Então teremos um parâmetro optional neste método. Veja como fica :

    <Description("Gera um adapter conforme configuração do manifesto")> _

    Public Function CriarAdapter(Optional ByVal bInterligarCommand As Boolean = False) As IDbDataAdapter

        Select Case iBanco
            Case eTipoBanco.OLEDB
                If Not bInterligarCommand Then
                    Return (New OleDb.OleDbDataAdapter)
                Else
                    Return (New OleDb.OleDbDataAdapter(cmd))

                End If

            Case eTipoBanco.SQL
                If Not bInterligarCommand Then
                    Return (New SqlClient.SqlDataAdapter)

                Else
                    Return (New SqlClient.SqlDataAdapter(cmd))

                End If
            Case Else
                Throw New ApplicationException("Erro de configuração na configuração do tipo de banco")

        End Select
    End Function

Desta forma, conforme o parâmetro recebido o método já faz a interligação entre o Command e o adapter ou não.

Vamos então partir para os métodos auxiliares. Vamos começar pelo CriarObjetosBanco. Veja como fica :

    <Description("Esta sub faz a criação de todos os objetos de banco para um acesso simples e os interliga")> _

    Public Sub CriarObjetosBanco()
        cn = CriarConexao()
        cmd = CriarCommand()
        cmd.CommandType = CommandType.StoredProcedure
        cmd.Connection = cn
        da = CriarAdapter(True)
    End Sub

Depois de termos criado os métodos anteriores este se torna bem simples. Utiliza os métodos já existentes para realizar uma configuração básica nos objetos de banco e os deixa disponíveis para serem acessados por outras classes.

Vejamos agora como fica o método ObterParametros, realizando a derivação de parâmetros :

    <Description("obtem os parametros de um command utilizando o commandbuilder adequado")> _

    Public Sub ObterParametros(ByVal cmd As IDbCommand)
        If TypeOf cmd Is OleDb.OleDbCommand Then
            Dim cb As New OleDb.OleDbCommandBuilder
            cb.DeriveParameters(cmd)
        ElseIf TypeOf cmd Is SqlClient.SqlCommand Then
            Dim cb As New SqlClient.SqlCommandBuilder
            cb.DeriveParameters(cmd)
        Else
            Throw New ApplicationException("Não é possível obter os parâmetros deste tipo de command - funcionalidade não implementada")

        End If
    End Sub

Para fazer a derivação de parâmetros precisamos de um CommandBuilder. Tendo criado este objeto basta fazer uma chamada simples ao método DeriveParameters.

Por fim, faltam apenas as propriedades para permitirem o acesso aos objetos de banco externamente :

    <Description("devolve o objeto de conexão armazenado nesta instância")> _

    Public ReadOnly Property conexao() As IDbConnection
        Get
            Return (cn)
        End Get
    End Property

 

    <Description("devolve o objeto command armazenado nesta instância")> _

    Public ReadOnly Property command() As IDbCommand
        Get
            Return (cmd)
        End Get
    End Property

 

    <Description("Devolve o objeto adapter armazenado nesta instância")> _

    Public ReadOnly Property DataAdapter() As IDataAdapter

        Get
            Return (da)
        End Get
    End Property

Agora a camada de dados

Tudo o que fizemos agora foi apenas referente ao componente para criar os objetos de dados e não a camada de dados em si. Agora sim iremos começar a criar o componente da camada de dados. Será apenas um, pois o que já fizemos na criação dos objetos de dados, tal como a derivação de parâmetros, permite uma grande generalização na camada de dados.

Nosso componente da camada de dados terá 2 métodos :

ExecutarProcedure : Para executar uma procedure que não gera dados como resultado.

ObterDadosProcedure : Para executar uma procedure que gera uma DataTable como resultado

ObterDadosProcedure

Este método deverá preencher uma DataTable com os dados retornados pela procedure. Esta dataTable pode eventualmente ser tipada ou não. A camada de dados, porém, precisará sempre tratar esta dataTable como não tipada para garantir o tratamento genérico.

A camada de negócio eventualmente desejará utilizar dataSets e dataTables tipadas, então este método deverá receber a dataTable a ser preenchida por parâmetro.

Outro parâmetro necessário para este método é uma coleção

    <Description("faz a execução de uma stored procedure e preenche uma datatable com o resultado")> _

  Public Function obterDadosProcedure(ByVal dt As DataTable, ByVal NomeProcedure As String, Optional ByVal parametros As Hashtable = Nothing) As DataTable

        'Cria os objetos de banco

        Dim banco As New clObjetosBanco
        Try
            banco.CriarObjetosBanco()
            banco.command.CommandText = NomeProcedure 

            'Faz a carga dos dados
            dt.BeginLoadData()
            Dim DTM As New Common.DataTableMapping("Table", dt.TableName)

            banco.DataAdapter.TableMappings.Add(DTM) 

            'Se houverem parâmetros para a procedure, faz o preenchimento 

            If Not IsNothing(parametros) Then
                banco.conexao.Open()
                banco.ObterParametros(banco.command)
                preencherParametros(banco.command, parametros)

            End If

            Dim ds As DataSet
            ds = dt.DataSet
            banco.DataAdapter.Fill(ds)
        Catch er As OleDb.OleDbException
            Throw New ApplicationException("Ocorreu erro durante o processo de obtenção do dataset!", er)

        End Try

        banco.conexao.Close()
        dt.EndLoadData()
        Return (dt)
    End Function

O adapter criado pelo componente de objetos de banco precisará preencher a datatable. Então precisaremos adicionar um DataTableMapping ao adapter para fazer a vinculação dos dados de origem com a dataTable que foi recebida como parâmetro.

A coleção de parâmetros é opcional. Se ela não tiver sido transmitida, ignoramos. Se tiver sido transmitida então precisamos fazer a derivação de parâmetros e preencher os parâmetros do command. Para este preenchimento vamos chamar uma sub a parte, preencherParametros.

Feito isso basta realizarmos o Fill do adapter. A interface IdbDataAdapter apenas permite o Fill direto em um dataset, então precisamos recuperar o dataSet a partir da dataTable e só então fazer o Fill.

PreencherParametros

A sub PreencherParametros é privada da camada de acesso a dados. Essa sub irá receber um command e uma hashTable e preencher os parâmetros do command com os valores contidos na HashTable.

    <Description("preenche os parâmetros de um command com base em uma datatable")> _

Private Sub preencherParametros(ByVal cmd As IDbCommand, ByVal parametros As Hashtable)

        Dim p As IDbDataParameter
        For Each p In cmd.Parameters

            'Verifica se o parâmetro existe na HashTable, para evitar erros com
            'parâmetros opcionais
            'hashtable é sensível a caixa da letra

            If parametros.Contains(LCase(p.ParameterName)) Then
                p.Value = parametros.Item(LCase(p.ParameterName))
            End If
        Next
    End Sub

Observe que tomamos o cuidado de checar se o parâmetro foi transmitido para que não seja gerado erro em caso de parâmetros opcionais.

ExecutarProcedure

O método executarProcedure recebe dois parâmetros, o nome da procedure e uma coleção de parâmetros para a procedure. Funciona de forma muito semelhante ao anterior, mas como não há retorno de dados não precisamos do dataAdapter, precisamos apenas de um Command.

O código configura o command, se houverem parâmetros faz a derivação e preenche os parâmetros, após isso executa o command.

    <Description("Faz a execução de uma stored procedure sem a obtenção de valor de retorno")> _

    Public Sub ExecutarProcedure(ByVal NomeProcedure As String, Optional ByVal Parametros As HashTable)

        Dim obj As New clObjetosBanco
        Dim cn As IDbConnection
        Dim cmd As IDbCommand

        cn = obj.CriarConexao
        cmd = obj.CriarCommand
        cmd.CommandType = CommandType.StoredProcedure
        cmd.CommandText = NomeProcedure
        cmd.Connection = cn

        cn.Open()

        If Not isnothing(parametros) Then
            obj.ObterParametros(cmd)
            preencherParametros(cmd, Parametros)
        End If

        Try
            cmd.ExecuteNonQuery()
        Catch er As Exception
            Throw New ApplicationException("ocorreu um erro na execução", er)

        End Try
        cn.Close()
    End Sub

Pronto, temos nosso componente para a camada de dados.

Com este componente que acabamos de criar os componentes de negócio poderão fazer acesso a banco de forma genérica, acessando procedures para recuperar dados, atualizar, deletar ou inserir dados.

Vejamos então a criação de um componente de negócio.

Componente de negócios

Na camada de negócios os componentes básicos de cadastramento terão todos os mesmos métodos :

Adicionar
Listar
Deletar

A procedure de inclusão pode realizar também atualização quando o registro já existir, então ficamos com um método a menos.

Mesmo na camada de negócios haverá muito código repetitivo, especialmente para as operações básicas. Podemos então criar uma classe base de negócios e aproveitar a herança no .NET para gerar todas as demais.

Então vamos começar vendo como ficam os métodos Adicionar e Deletar :

    Public Sub Adicionar(ByVal hs As Hashtable)
        ExecutarProc(getProcAdicionar, hs)
    End Sub

    Public Sub Deletar(ByVal hs As Hashtable)
        ExecutarProc(getProcDeletar, hs)
    End Sub

Ambos os métodos irão executar procedures passando parâmetros para elas. Portanto para não duplicar o código criamos um método privado chamado ExecutarProc. Este método recebe como parâmetro o nome da procedure e uma coleção com os parâmetros para a procedure.

Mas observe ainda que não utilizei o nome da procedure nestes dois métodos. Isso porque estamos desenvolvendo uma classe base, para ser herdada, então cada uma das sub-classes deverá especificar o nome de suas próprias stored procedures. No local onde entraria o nome da procedure foram feitas chamadas a diferentes subs privadas. São subs definidas com o mustOverride, da seguinte forma :

    Protected MustOverride Function getProcAdicionar() As String
    Protected MustOverride Function getProcDeletar() As String

Assim sendo quando formos criar uma classe de negócios bastará herdar desta classe base e especificar o nome das procedures através destas funções.

ExecutarProc

Esta sub é bem simples, apenas faz uso do componente de acesso a banco que já construimos para fazer a execução de uma procedure :

    Private Sub ExecutarProc(ByVal nomeProc As String, ByVal hs As Hashtable)

        Dim bd As New clDados.clAcessoDados
        bd.ExecutarProcedure(nomeProc, hs)
    End Sub

Listar

O método listar se difere um pouco dos dois anteriores pois deverá receber um conjunto de dados, portando deverá chamar o método obterDadosProcedure. Conforme vimos anteriormente, este método espera receber uma dataTable, tipada ou não tipada. Então o listar será o responsável por criar esta nova dataTable.

Porém estamos criando uma super classe que será herdada pelas classes de negócio específicas, portanto não devemos criar nesta super classe um dataset específico. Vamos então solucionar este problema da mesma forma que fizemos com os nomes das procedures : Criando uma função com mustOverride que devolva um dataSet.

    Public Function Listar(Optional ByVal hs As Hashtable = Nothing) As DataSet

        Dim obj As New clDados.clAcessoDados
        Dim dt As DataTable 

        dt = obj.obterDadosProcedure(getDataTable, getProcListar, hs)

        obj = Nothing
        Return (dt.DataSet)
    End Function

Este método Listar utiliza 2 funções com mustOverride, veja como elas ficam :

    Protected MustOverride Function getProcListar() As String

    Protected MustOverride Function getDataTable() As DataTable

Criando um componente de negócio específico

Vejamos agora como fica o código para a criação de um componente de negócio específico através da classe base que acabamos de criar :

Public Class CadProdutos
    Inherits clNegocios.clNegocioBase

    Protected Overrides Function getProcAdicionar() As String
        Return "stp_adicionar_produtos"
    End Function

 

    Protected Overrides Function getProcDeletar() As String
        Return "stp_deletar_produtos"
    End Function

 

    Protected Overrides Function getProcListar() As String
        Return "stp_Listar_Produtos"
    End Function

 

    Protected Overrides Function getDataTable() As DataTable
        Dim _DataBase As New dsProdutos
        Return _DataBase.Tables("tbl_produtos")
    End Function
End Class

Fig.1 : um pequeno modelo das classes geradas

 

 

Conclusão

Esta é apenas uma das formas possíveis para montarmos uma camada de dados e de negócios com .NET. Muitas outras variações podem ser criadas.

O componente da camada de dados pode ser ampliado para oferecer maiores recursos, como por exemplo execuções múltiplas de procedures (inserção de muitos registros), retorno de parâmetros de output, entre outros recursos.

Mostrei apenas a montagem desta arquitetura com relação a acesso a dados. Esses componentes mostrados aqui precisam ainda de tratamento de erros, sistema de logs, etc.

Neste exemplo fiz a transferência de dados entre as camadas com hashTable, mas isso pode variar, pode-se até mesmo utilizar uma DataTable.

Dennes Torres
MCAD,MCSD,MCSE,MCDBA





Envie seus comentários sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentários nesta página

Veja abaixo os comentários já enviados :

Nome : Adriano Cavalcanti E-Mail : cryscow@lycos.com
Olá Amigo ,

Sou novato no .NET , e gostei muito da matéria .
Gostaria de fazer um pedido.
Você não teria Este mesmo Modelo feito em C#.



Adriano Cavalcanti
cryscow@hotmail.com
cryscow@lycos.com
Nome : Marcelo Refosco E-Mail : refosco@terra.com.br
Olá Dennis,

Caso eu queira criar um provider ODBC no Asp.NET 2.0, como devo proceder, visto que no mesmo só há dois providers: AccessMembershipProvider e SqlMembershipProvider???

Obrigado,
Marcelo.
Nome : Dennes Torres E-Mail : dennes@bufaloinfo.com.br

No .NET 2.0 o que é chamado de SQLDataSource na verdade é uma origem de dados a qualquer banco SQL, quer seja via ODBC, OLEDB, ou outros data providers. O SQL DataSource não é um dataProvider, durante a configuração dele você deverá escolher o dataprovider que irá utilizar.

Nome : Germano E-Mail : germano@aliancaportasejanelas.com.br
Beleza Amigo,

Gostaria de saber se vc saberia como fazer uma conexão e manipulação de uma tabela access dentro de um projeto para Pocket PC (smart Device).

Obrigado

Germano Ribeiro Santiago
Nome : Valter E-Mail : vjmaurin@ibestvip.com.br
muito bom este exemplo, pois gostaria de umas dicas, aguardo por e-mail.
Nome : Marco Pellicciotta E-Mail :
Dennes,

Parabéns! Este é o verdadeiro conceito da orientação a objeto: Deixar o trabalho por conta das classes e escrever o mínimo de código repetitivo possível.

Marco Pellicciotta, MCAD(.NET)
Nome : Nilo Ferreira E-Mail : nilo_ferreira@hotmail.com
Dennes,

sou novo nisso de programação em camadas.. então peguei o seu exemplo para trabalhar.. montei as classe em C#, mas eu não sei como aplicar esse's objeto's no meu formularios
Nome : Felipe Augusto de Jesus Carvalho E-Mail : felipeaugustojc@yahoo.com.br
Excelente a matéria!!! O conceito de OO está perfeito!
Nome : juliano E-Mail : jsegoa@pop.com.br
Olá, achei excelente esta matéria mas estou com dúvidas na implementáção do metodo
Protected Overrides Function getDataTable() As DataTable
Dim _DataBase As New dsProdutos
Return _DataBase.Tables("tbl_produtos")
End Function
Pois fiquei confuso com a classe dsProtudos que náo existe como fasso isso?
Obrigado
Nome : Cristiano E-Mail : cristiano.vbs@hotmail.com
Estou com dificuldades em implementar estas classes com windows form.... poderia me dar um exemplo???

depois de compiladas eu posso simplesmente referenciá-la em meu projeto??
obrigado pela atenção!

Cristiano
Nome : Viviane E-Mail : viviane.lorencon@terra.com.br
Olá, achei este artigo muito interessante, estou me baseando nele pra criar minhas camadas. Fiquei com dúvida no seguinte trecho:

Protected Overrides Function getDataTable() As DataTable
Dim _DataBase As New dsProdutos
Return _DataBase.Tables("tbl_produtos")
End Function

A classe dsProdutos não existe, seria um dataset? Está dando erro e não consigo fazer funcionar...

Obrigada!
Obrigada!
Nome : Edivaldo Rosa da Cunha E-Mail : edivaldocunha@uol.com.br
Gostaria de saber se existe no mercado um Sistema de banco de dados que me possibilite ter acesso via internet a dados cadastrais dos meus alunos como CPF,RG,ENDEREÇO,TEL, CURSO, MODULO, PROFESSOR, FREQUÊNCIA, NOTA, OBS.:, QUANTIDADE DE PARCELAS A PAGAR, PARCELAS EM ATRASO + JUROS.Este sistema deve me possibilitar acesso a todas as informações(Diretor da escola) e possibilitar aos professores o acesso a informações não restritas.
Estou necessitando desta informação para concluir um Projeto Academico.
Se for possivel ficarei muito grato.
Nome : Juliano Gimenez E-Mail : juliano_gimenez@hotmail.com
TENHO A MESMA DUVIDA DA VIVIANE...

Olá, achei este artigo muito interessante, estou me baseando nele pra criar minhas camadas. Fiquei com dúvida no seguinte trecho:

Protected Overrides Function getDataTable() As DataTable
Dim _DataBase As New dsProdutos
Return _DataBase.Tables("tbl_produtos")
End Function

A classe dsProdutos não existe, seria um dataset? Está dando erro e não consigo fazer funcionar...

Obrigada!
Nome : Nadia E-Mail : nadiateles@hotmail.com
Olá, bom dia.

Sou novata no .NET e gostei muito da matéria. Estou estudando a criação desta camada.

Você poderia disponibilizar este mesmo modelo em C#?

obrigada
Nome : Paulo Meireles E-Mail : paulo@meireles.com.br
Ol? Dennes, bom dia!

Sou estudante de programa??o e estou iniciando meus estudos em arquitetura em camadas. Como gostei muito de teu artigo, queria te perguntar se terias algumas outras refer?ncia de artigos que complementassem meus estudos.

Parab?ns!

Obrigado, Paulo
Nome : WMIs9wND6zbc E-Mail : vzg1xd3g9u0@yahoo.com
Moi je sais of9 elle e9tait passe9e! Je l'ai croise9e sur la lune of9, incroyable mais vrai elle se de9plae7ait en ski!
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : peUlYbTPUU8j E-Mail : qq4ijnzm@hotmail.com
That's the best answer by far! Thanks for coruiibttnng.
Nome : adidas nmd E-Mail : skgoss@gmail.com
Thanks for all your valuable effort on this website. My niece enjoys going through research and it is simple to grasp why. Most people know all of the compelling mode you convey effective tricks by means of your blog and foster participation from some others on this content while my daughter is now becoming educated so much. Take advantage of the rest of the year. You're the one carrying out a brilliant job.
adidas nmd https://v.gd/MHqMLq

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

� Búfalo Informática, Treinamento e Consultoria - Rua Álvaro Alvim, 37 Sala 920 - Cinelândia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br