Ir para conteúdo
Fórum Script Brasil
  • 0

Banco De Dados (access 2003)


Denis Bittencourt Muniz

Pergunta

Tenho esse código:

<% @ Page Language = "C#" %>

<% Response.Expires = 0; %>


<% object objConn, objRS; %>

<% 

objConn = Server.CreateObject("ADODB.Connection");
objConn.Open("DSN=Funcionarios;Database=Funcionarios;UID=;PWD=;");

objRS = Server.CreateObject("ADODB.Recordset");
objRS.ActiveConnection = objConn;
objRS.Open("SELECT * FROM Funcionarios");

while(! objRS.EOF){
	Response.Write(objRS("Nome")+"<br>");
	objRS.MoveNext;
}

objRS.Close;
objConn.Close;
objRS = null;
objConn = null;

%>

E dá esse erro:

CS0117: 'object' does not contain a definition for 'Open'

Nessa linha:

objConn.Open("DSN=Funcionarios;Database=Funcionarios;UID=;PWD=;");

Mas no caso, qual seria o tipo de variável que eu usaria, pois entendi o que o tipo object não é o tipo correto.. Qual seria? Alguma solução?

Falows!

Link para o comentário
Compartilhar em outros sites

1 resposta a esta questão

Posts Recomendados

  • 0

C# é fortemente tipada e não tem o recurso de late-binding existente no VB. Ou seja, *nós* sabemos que estes métodos e propriedades existem no objeto quando o mesmo é criado. Porém, o compilador não sabe e nem vai saber até que o objeto seja de fato criado, o que só ocorre durante a execução. Por isso que esse código acima não funciona no C# (mas funciona no VB).

Aliás, uma vez fiz um artigo exatamente sobre isso. Não me lembro onde que ele está na web, mas segue a cópia do mesmo que tenho aqui:

Utilizando a técnica de Late-Binding em C#

A tecnologia COM/ActiveX será um legado que perdurará por muito tempo, e pode ser que a substituição de um sistema antigo por um novo implique na reutilização de componentes deste tipo. Pensando nisso, a Microsoft fez com que a .NET Framework fosse 100% compatível com esta tecnologia (para nossa felicidade!). Porém, é comum a utilização de componentes COM através de late-binding, ou seja, através de um processo em que o componente, seus métodos, propriedades, etc. são resolvidos em tempo de execução. A vantagem disso é a fácil substituição do componente, sem efeitos colaterais. O uso de late-binding em VB.NET é super-amigável, já que é uma característica própria da linguagem (já estava presente desde versões passadas da linguagem, na era pré-.NET). Nesta, a utilização de um objeto COM não difere de qualquer outro objeto criado nativamente. Em C# já não se tem essa facilidade, e esse foi o principal motivo para que este artigo fosse realizado: em C# precisa-se utilizar Reflection para manipulação de componentes COM através de late-binding.

Em VB.NET emprega-se a técnica de duck-typing[1] (do inglês, "tipagem pato") quando se utiliza o tipo Object, que vem de um conceito simples porém muito interessante: "se anda e grasna como um pato, então é um pato!". Ou seja, não importa qual o tipo do objeto, desde que ele ofereça a interface que esperamos (métodos, propriedades, eventos, etc.). Daí, conclui-se que tanto faz se o objeto é um "pato" ou um "marreco", desde que os métodos valham para ambos. Por essa razão é que o código abaixo é válido:

Module Exemplo
    Sub Main()
        Dim winword As Object = CreateObject("Word.Application")
        winword.Documents.Add()
        winword.Selection.TypeText("teste")
        winword.Visible = True
    End Sub
End Module
É de conhecimento geral que todos os aplicativos da suite Microsoft Office podem ser automatizados através de objetos COM, e no exemplo acima o Microsoft Word é utilizado nesse sentido. Como o foco do artigo não é a automação do Microsoft Office, e sim a utilização de objetos COM em geral, o exemplo é simplório e visa apenas demonstrar a resolução em tempo de execução de métodos, objetos e propriedades. O objeto "winword", por ser do tipo Object, só possui, de verdade, um único método chamado GetType(). No entanto, o compilador não reclama de fazermos referência a objetos, métodos e propriedades contidos nele. *Nós* sabemos que eles existirão quando o programa estiver sendo executado, por isso deixamos com que sejam resolvidos durante a execução. Vale ressaltar que a diretiva Option Strict deve estar como Off, que já é o padrão, para que isso seja permitido. Caso Option Strict esteja ligada (On), o comportamento do VB.NET será o mesmo de C#, ou seja, ele resolverá os métodos e atributos em tempo de compilação. Em contrapartida, C# é fortemente tipada, o que significa que não adianta você entregar um "marreco" no lugar de um "pato"; o compilador vai reclamar. É claro que existem formas de remediar isso através de herança (através do polimorfismo dinâmico, é possível passar um objeto filho para um objeto do tipo pai), interfaces e classes abstratas. Através destas últimas duas, qualquer classe que herde/implemente-as, obrigatoriamente, obedecerá ao esquema definido na interface/classe. Para isso, criar-se-ia uma classe, interface ou classe abstrata chamada Anatídeo (nome da família dos patos e marrecos) e herdar/implementar-se-ia ela nas classes Pato e Marreco. É claro que essas são soluções mais sensatas quando se está criando classes que são substituíveis por outras compatíveis. Todavia, o nosso caso aqui é utilizar componentes já prontos, cujas interfaces não são a preocupação maior. A mistura feita aqui entre COM/duck typing/interfaces/late-binding é proposital: duck typing é um meio interessante de se utilizar componentes COM através de late-binding sem a utilização "direta" de interfaces. Sua aplicação não fica "presa" a determinado componente (de uma certa forma). Alguns questionam essa maneira de se programar, mas não acredito que ela possa ser condenável. Em todo caso, esse não é o foco do artigo por isso não enveredaremos por esse caminho. Vejamos agora como ficaria em C# aquele mesmo exemplo ali de cima, que abre o Word, escreve "teste" e o torna visível:
using System;
using System.Reflection;

class Exemplo
{
	static void Main(string[] args)
	{
  Type tipoWord = Type.GetTypeFromProgID("Word.Application");
  Type tipoDocuments, tipoSelection;

  object winword = Activator.CreateInstance(tipoWord);
  object Documents, Selection;

  Documents = tipoWord.InvokeMember("Documents", BindingFlags.GetProperty, null, winword, new Object[] {});
  tipoDocuments = Documents.GetType();
  tipoDocuments.InvokeMember("Add", BindingFlags.InvokeMethod, null, Documents, new Object[] {});

  Selection = tipoWord.InvokeMember("Selection", BindingFlags.GetProperty, null, winword, new Object[] {});
  tipoSelection = Selection.GetType();
  tipoSelection.InvokeMember("TypeText", BindingFlags.InvokeMethod, null, Selection, new Object[] {"teste"});
  
  tipoWord.InvokeMember("Visible", BindingFlags.SetProperty, null, winword, new object[] {true});
	}
}
A primeira coisa que temos que notar é que, como não temos o objeto em si para manipular seus métodos e propriedades, precisamos utilizar seu tipo (Type) para fazer as chamadas. No caso, tipoWord é o tipo de Word.Application, tipoDocuments é o tipo de Word.Application.Documents e o tipoSelection é o tipo de Word.Application.Selection. Usando o método CreateInstance() da classe Activator, podemos então criar um objeto da classe (tipo) tipoWord, que ficará referenciado pelo objeto winword. O tipo de winword é Object, o tipo pai-de-todos, ou seja, aquele que pode armazenar uma referência para qualquer objeto de qualquer classe. Todavia, como já foi dito antes, apesar de sabermos que esse objeto terá outros métodos e propriedades, além das já existentes em qualquer Object, o compilador não nos deixará usá-los. Isso porque eles não estão realmente lá, só surgindo em tempo de execução. Dessa maneira, para fazermos...
winword.Documents.Add()

... temos que primeiro obter o objeto Documents que está contido em winword. E, do mesmo modo, teremos que obter o tipo (Type) de Documents para poder manipulá-lo (tipoDocuments), o que é feito através do método GetType() do objeto. Só então é que poderemos chamar o método Add() do mesmo. E segue-se o mesmo procedimento para obter Selection e chamar seu método TypeText().

O ponto vital aqui é o método InvokeMember() que capaz, como o nome sugere, invocar um membro do referido objeto. Por membro, podemos destacar métodos, propriedades e campos públicos. Vamos nos estender um pouco mais sobre este método agora.

Vou me atear à assinatura de InvokeMember utilizada aqui:

public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args);

O primeiro parâmetro de InvokeMember (name) é o nome do membro a ser "invocado", passado em uma string. O segundo parâmetro (invokeAttr) é como vamos invocar o desejado membro. Algumas possibilidades para isso são:

InvokeMethod - para chamar um método

GetProperty - para obter o valor de uma propriedade

SetProperty - para definir o valor de uma propriedade

Basicamente vou me ater a estes, já que são os utilizados aqui. Estas constantes e as demais podem ser encontradas na classe BindingFlags (dentro de System.Reflection).

O próximo parâmetro (binder) é um objeto Binder, que serve para fazer conversões de tipos ao invocar o membro; como uma camada para fazer ajustes nos parâmetros. No nosso caso isso não é importante, por isso pode-se passar simplesmente null (Nothing no VB.NET) para que seja utilizado o binder padrão.

O parâmetro seguinte (target) é o próprio objeto em questão, o alvo. Uma vez que estamos pedindo ao tipo para invocar o membro do objeto, temos que informar qual o objeto. Ou seja, podemos ter apenas uma referência ao tipo (tipoWord) e ter vários objetos dele (winword1, winword2, winword3, etc.), utilizando o mesmo tipo para manipular todos os objetos (já que estes são explicitamente passados).

O último parâmetro (args) é um array de object no qual informaremos os parâmetros a serem passados para o método/propriedade/campo, etc. Ao chamar o método TypeText, no exemplo acima, temos um array de object com uma string (com o texto "teste"), porque este é o único parâmetro a ser passado para o método. Outro exemplo é para tornarmos o Word visível, o que é feito pela propriedade Visible, no qual criamos um array de object apenas com true. Se fossem dois, três, quatro, n-parâmetros, todos eles deveriam ser informados nesse array (e como é um array de Object, todos os outros tipos podem ser comportados).

[1] http://en.wikipedia.org/wiki/Duck_typing

Mas, acredito que o melhor para o seu caso seria a utilização do ADO.NET que é o método nativo da .NET Framework para acesso a dados. Dê uma procurada aqui no fórum e você encontrará exemplos.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      652k
×
×
  • Criar Novo...