terça-feira, 7 de outubro de 2008

Mini-tutorial SharePoint Smart Part

Aqueles que já desenvolveram Web Parts para o Microsoft Office SharePoint Services puderam notar que a Microsoft não facilitou em nada esta tarefa para o Desenvolvedor. A criação de uma Web Part é muito parecida com a criação de um Server Control: isso significa que todo o HTML que a Web Part irá exibir no browser deve ser gerado no código (VB.Net ou C#). Para Web Parts complexas, com formulários, validações, AJAX e etc. ,isso pode acabar com a produtividade no desenvolvimento.

Para contornar essa dificuldade, existe um projeto Open-Source chamado Smart Part. Nesse projeto, foi criada uma Web Part que nada mais faz do que injetar um User Control dentro de si mesma, ou seja: nos dá a opção de criar Web Parts como User Controls (ascx). Isso ajuda muito a produtividade e torna bem mais simples o desenvolvimento de novas funcionalidades para o Sharepoint.

A seguir, mostrarei como criar uma Smart Part simples:

  1. Baixe e descompacte o Smart Part neste link: http://www.codeplex.com/smartpart/Release/ProjectReleases.aspx?ReleaseId=10697
  2. Crie um novo projeto Web Application no Visual Studio e adicione uma referência para o assembly ReturnOfSmartPart.dll.
  3. Crie um User Control (ascx) da mesma forma como você faria num projeto de Web Site comum.
  4. Instale o Smart Part no servidor onde está o SharePoint. Se houver mais de uma Aplicação do Sharepoint instalada, você poderá escolher em quais deseja instalar.
  5. Abra o diretório do Sharepoint para o qual o IIS aponta, por exemplo: “C:\Inetpub\wwwroot\wss\VirtualDirectories\[NumeroDaPorta]”. Onde [NumeroDaPorta] é o número da porta que a Aplicação Sharepoint está configurada (80, por exemplo).
    1. Jogue as DLLs que seu projeto gerou na pasta Bin.
    2. Crie uma pasta chamada User Controls na raiz e copie o ascx para ela.
  6. Abra uma página no Sharepoint e adicione a Web Part Smart Part nela.
  7. Clique no menu da Web Part (seta no canto superior-direito da Web Part), e clique em “Modify Shared Web Part”.
  8. No Tool Part que apareceu à direita, deve existir um campo chamado “User Control to Display”, ele exibe todos os User Controls encontrados na pasta UserControls da raiz da pasta do Sharepoint, selecione o seu ascx.

Pronto! Muito mais simples do que desenvolver uma Web Part, com a vantagem de poder utilizar o designer do Visual Studio para criar o XHTML do ascx.

Referência:
Site do projeto: http://www.codeplex.com/smartpart

segunda-feira, 15 de setembro de 2008

Busca com Procedure Utilizando Castle Activerecord

Olá! Recentemente me deparei com um desafio interessante: criar um mecanismo de busca para todo um site (que possui diversos módulos, e cada um com suas tabelas no SGBD), sendo que este site havia sido desenvolvido utilizando o Castle Activerecord. Para fazer isso, encontrei 3 caminhos possíveis:
  1. Para cada módulo, desenvolver uma busca utilizando o Activerecord, depois criar uma classe que executa todas essas buscas e junta os resultados.
    • Esta solução tem 3 grandes problemas: esforço muito grande para criar essa busca, não é nada amigável para manutenção (em alguns casos teria que alterar o código da busca de cada módulo para implementar uma nova característica, e não permite utilizar plenamente características de busca do SGBD que eu estava utilizando (Full-Text Search do SQL Server 2005).
  2. Desenvolver uma query em HQL que busque em todos os módulos.
    • Esta solução é mais interessante que a anterior, ela resolve o problema do esforço e em parte também resolve o problema da manutenção. Somente em parte porque é difícil dar manutenção em queries HQL, não há breakpoints e os erros que o NHibernate gera são confusos. Quanto à possibilidade de utilizar o Full-Text Search, também não seria possível nesta solução.
  3. Desenvolver uma stored procedure de busca e utilizá-la através do NHibernate.
    • Esta foi a slução que escolhi, pois do ponto de vista da manutenção é mais simples pois procedures em T-SQL são fáceis de alterar e não é necessário muito código para utilizá-las através do NHibernate. O esforço é pequeno para o desenvolvimento (uma classe simples e uma procedure de complexidade média). Finalmente, esta solução permite que eu utilize quaisquer características do SGBD.

A solução que escolhi também tem problemas: utilizando ela estou "violando" a arquitetura proposta para o site, pois não utilizarei o ActiveRecord e criarei uma nova camada de lógica dentro do SGBD. Outro problema é que a solução não é independente de SGBD, se um dia o SQL Server for trocado por um Oracle, por exemplo, a procedure deverá ser reescrita. Porém, analisando os prós e contras de todas as alternativas, ela se mostrou a mais adequada para a situação.

Como desenvolver

Primeiramente, criei uma enumeração com todos os módulos nos quais seriam feitas as buscas:

Public Enum Modulo as Byte
Modulo1
Modulo2
Modulo3
End Enum
Depois, criei uma classe para guardar os resultados da busca:
Public Class Busca
Private _Titulo As String
Public Property Titulo() As String
Get
Return _Titulo
End Get
Set(ByVal value As String)
_Titulo = value
End Set
End Property
Private _ModuloRelacionado As Modulo
Public Property ModuloRelacionado() As Modulo
Get
Return _ModuloRelacionado
End Get
Set(ByVal value As Modulo)
_ModuloRelacionado = value
End Set
End Property
Private _ID As String
Public Property ID() As String
Get
Return _ID
End Get
Set(ByVal value As String)
_ID = value
End Set
End Property
End Class
Após isso, criei a procedure com a busca, esta procedure recebe um parâmetro chamado @Keywords e devolve uma tabela com os campos: ID, ModuloRelacionado e Titulo.
Depois de criar a procedure, adicionei um método na classe Busca que executa a procedure, devolvendo seu resultado como um vetor de Buscas:
Public Shared Function Buscar(ByVal KeyWords As String) As Busca()
Dim s As NHibernate.ISession = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(GetType(Busca))
Dim q As NHibernate.IQuery = s.CreateSQLQuery("exec pr_Busca ?").AddScalar("Titulo", NHibernate.NHibernateUtil.String).AddScalar("ModuloRelacionado", NHibernate.NHibernateUtil.Byte).AddScalar("ID", NHibernate.NHibernateUtil.String).SetResultTransformer(New NHibernate.Transform.AliasToBeanResultTransformer(GetType(Busca)))
q = q.SetString(0, KeyWords)
Return DirectCast(q.List(Of Model.Busca)(), Generic.List(Of Model.Busca)).ToArray()
End Function

Neste método, primeiro inicio uma nova sessão do NHibernate.
Depois, crio uma nova Query em SQL (não HQL). Para cada atributo que meu conjunto de resultados possuir, executo o método AddScalar, passando o nome desse atributo e seu tipo.
O método SetResultTransformer informa o objeto que o NHibernate deverá utilizar para fazer a transformação dos resultados da forma relacional para objetos, neste caso utilizei o AliasToBeanResultTransformer, que para cada registro retornado cria um novo objeto e para cada atributo dos registros procura uma property no objeto criado com o mesmo nome do atributo e copia seu valor:

Após isso, insiro o valor do parâmetro da procedure e executo o método List, que executa a procedure e devolve o resultado como IList, o qual eu converto em um vetor utilizando o método ToArray().

Dessa forma, a solução ficou simples e atendeu a necessidade de encapsular a busca do site.

Abrassssss!

quinta-feira, 14 de agosto de 2008

Configurando o Castle ActiveRecord em aplicações web

Configurar o Castle ActiveRecord em aplicações web é uma tarefa fácil. Porém, as documentações oficiais sobre isso são um pouco confusas. Neste post pretendo mostrar da forma mais simples possível como fazer uma configuração básica do Castle ActiveRecord.

Primeiro Passo - Instale os assemblies no computador de desenvolvimento

O site oficial do Castle ActiveRecord disponibiliza um instalador que registra os assemblies em seu computador de desenvolvimento, isso facilita na hora de referenciar no seu projeto, os assemblies aparecerão entre as referências do .Net na janela Add Reference do Visual Studio.
Se você preferir, pode apenas baixar e copiar os Assemblies para seu computador.
Página de download do site oficial

Segundo Passo - Adicione as referências ao seu projeto

Adicione as seguintes referências, elas vêm no pacote baixado do site oficial.

  • Castle.ActiveRecord.dll
  • NHibernate.dll

Se você usou o instalador para instalar os assemblies, eles estarão na aba .Net da janela Add Reference do Visual Studio. Caso contrário, procure-os manualmente.

Terceiro Passo - Configure o web.config

Para SQL server, o web.config deverá ficar assim:

















Para o Oracle, deverá ficar assim:


















Quarto Passo - Inicialização do Framework no global.asax

Por fim, é necessário codificar a inicialização do Castle ActiveRecord, que deverá acontecer somente na inicialização da aplicação web. Para isso, devemos chamar o método Initialize da classe ActiveRecordStarter, passando as configurações que guardamos no web.config e todos os tipos que criamos que extendem a classe ActiveRecordBase. Ex:


Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the session is started
Dim _Config As Castle.ActiveRecord.Framework.IConfigurationSource
_Config = System.Configuration.ConfigurationManager.GetSection("activerecord")
Castle.ActiveRecord.ActiveRecordStarter.Initialize(_Config, _
GetType(Blog), _
GetType(Post) _
)
End Sub

Caso você não possa modificar o código do global.asax (se você está usando DotNetNuke, por exemplo), você pode fazer a inicialização em um HttpModule. Porém, como a inicialização de um HttpModule não acontece sempre quando a aplicação web inicializa (as vezes um HttpModule é inicializado mais de uma vez), você deverá usar um work-around: crie uma classe com o código da inicialização em seu contrutor estático e, no evento Init do HttpModule, apenas chame um método qualquer da classe onde está a inicialização (não precisa ter nenhum código neste método). Em breve postarei sobre esta técnica com mais detalhes.

quinta-feira, 7 de agosto de 2008

Princípios de Design Orientado a Objetos

A etapa de arquitetura de software é crucial para o futuro de qualquer projeto de sistema. Ela é feita logo antes da fase de construção do projeto e se bem planejada, ajudará bastante o projeto ser bem sucedido. Porém, uma arquitetura mal planejada é garantia de um projeto com problemas em diversas fases, desde a construção até a manutenção.
Em grandes projetos existe uma separação clara de papéis que define quem deverá ser responsável pela tarefa de definir a arquitetura do software, que geralmente é feita por uma pessoa especializada nisso, o Arquiteto de Software. Porém, em projetos ou empresas menores, observamos que essa tarefa geralmente é realizada por outras pessoas, como o Analista de Sistemas ou o próprio Desenvolvedor. Desta forma, estudar arquitetura de software é essencial não só aos que são (ou pretendem ser) arquitetos de software.
Neste post pretendo apresentar uma introdução à arquitetura de software orientada a objetos, essencial para quem deseja (ou precisa) arquitetar um software.

Quando decidimos desenvolver um software utilizando o paradigma da orientação a objetos, o fazemos com dois objetivos principais em mente, que são:

Diminuir o acoplamento
Ou seja, deixar as partes do sistema fáceis de de ser trocadas ou utilizadas por outras partes.
Aumentar a coesão
Ou seja, fazer com que as partes do sistema tenham excelência em fazer aquilo que se propõem sem depender de outras partes.

Robert Martin, em seu livro Agile Software Development: Principles, Patterns, and Practices, nos mostra alguns princípios que se bem observados na arquitetura do software orientado a objetos, trazem agilidade no desenvolvimento, estabilização, implantação e manutenção dos projetos.

Estes princípios nos ajudam a atingir os nossos dois objetivos tentando remover do software as seguintes características:

Rigidêz
Que é a dificuldade de fazer uma alteração numa parte do software porque ela afetaria muitas outras partes.
Fragilidade
Que é o surgimento de erros em diversas partes do software quando você altera alguma parte.
Imobilidade
Que é a impossibilidade de reutilizar partes do software porque não é possível "desencaixá-las" de todo o resto.

Sabendo isso, vamos aos princípios:

Princípio Aberto-Fechado

Classes, módulos e funções devem ser abertas para extensão, mas fechadas para modificações.
Ou seja: ao criar um sub-classe, por exemplo, você não deverá alterar nada no comportamento da classe base, ela deve permanecer intacta.Utilizar classes abstratas ou interfaces ajudam a reforçar este princípio.

Princípio da Inversão de Dependência

Partes de mais alto nível não devem depender das partes de menor nível. Ambas devem depender de abstrações; e
Abstrações não devem depender de detalhes. Os detalhes é que devem depender de abstrações;
Ou seja: Entre as classes de alto nível e as classes de baixo nível, devemos introduzir classes abstratas.
Isso permite que troquemos facilmente as classes de baixo nível sem afetar as de alto nível.
Para fazer isso, a parte abstrata deve ser definida e depois não mais alteradas (Aberto-Fechado), isso significa que devemos fazer as classes específicas (detalhes) seguindo as abstrações e caso a abstração não sirva, devemos extendê-la: nunca alterá-la.

Princípio da Segregação de Interfaces

Clientes não devem ser forçados a depender de iterfaces que eles não usam
Ou seja: devemos tomar cuidado ao criar interfaces para não colocarmos métodos nela que não são realmente necessários para qualquer classe que implemente essa interface.
Interfaces com métodos desse tipo são chamadas de interfaces poluídas. Devemos evitá-las.

Princípio da Responsabilidade Única

Uma classe deve ter uma única razão para mudar
Ou seja: uma classe deve ter uma única razão para mudar. Se identificarmos que ela está com mais de uma razão para mudar, devemos separá-la em duas classes.

Princípio da Substituição de Liskov

Sub-tipos devem ser completamente substituíveis por seu tipo-base
Ou seja: isso reforça o princípio Aberto-Fechado. Se você utilizar um objeto e através do polimorfismo manipulá-lo como sendo do seu tipo base, ele deve funcionar corretamente e deve se comportar da mesma forma como se comportaria se ele realmente fosse daquele tipo.

Os Design Patterns, tão falados atualmente, são "receitas" de como resolver determinados problemas corriqueiros seguindo os princípios aqui apresentados.
Seguindo estes princípios, com certeza ganhamos agilidade no desenvolvimento de software, além de aumentarmos, e muito, a qualidade dele. Uma coisa importante que não podemos deixar de ter em mente é que princípios não são regras, nós devemos sempre saber quando abrir mão de um princípio para não deixarmos o software desnecessariamente complexo.

Espero que isto possa ajudar a quem está se deparando com a tarefa de definir a arquitetura de um software e não sabe por onde começar. Abrasssss!

terça-feira, 13 de maio de 2008

Criando configurações utilizando configSections customizados

Olá! Neste post pretendo apresentar uma forma mais elegante do que o AppSettings para amazenar as configurações de aplicativos.

De cada 10 aplicações que desenvolvemos, 9 precisam de parâmetros de configuração. Normalmente utiliza-se o web.config (para aplicações ASP.Net) ou o app.config (para aplicações Console ou Windows) para armazenar as configurações. Normalmente vemos o seguinte:


<appsettings>
<add key="Parametro1" value="ValorDoParam1">
<add key="Parametro2" value="ValorDoParam2">
</appsettings>


Esta abordagem é simples e normalmente atende nossas necessidades. Porém ao utilizar esta abordagem temos os seguintes problemas:

  • Este espaço é compartilhado, o que torna mais difícil e suscetível a erros a configuração e manutenção

  • Todos os dados são armazenados como String e não possuem nenhum tipo de validação para o tipo que eles realmente representam

  • Não é possível armazenar estruturas complexas, como objetos por exemplo

Recentemente me deparei com uma alternativa muito interessante para melhorar a forma de armazenar configurações utilizando o Namespace System.Configuration do .Net Framework.
Esta alternativa nos permite criar seções dentro dos arquivos de configuração customizadas. Estas seções terão classes de fachada para recuperar (de uma forma simples) as configurações armazenadas de forma estruturada.

Para criar a classe de fachada, basta herdar da classe System.Configuration.ConfigurationSection e definir propriedades que devolvem as configurações que virão do arquivo de configuração, exemplo:

<!-- O trecho a seguir configura as secões customizadas do arquivo de configurações -->
<configSections>
<section name="ExemploConfig" type="ExemploConfiguracao.Configuration, ExemploConfiguracao"/>
</configSections>

<!-- A Seguir estão as configurações armazenadas no trecho configurado anteriormente -->
<ExemploConfig SaveLog="True" />

Para a configuração acima teríamos a classe abaixo:

Public Class Configuration
Inherits System.Configuration.ConfigurationSection

<System.Configuration.ConfigurationProperty("SaveLog", IsRequired:=True)> _
Public ReadOnly Property SaveLog() As Boolean
Get
Return Convert.ToBoolean(MyBase.Item("SaveLog"))
End Get
End Property
End Class


Neste exemplo, a classe Configuration serve de fachada para a recuperação das configurações. Para acessar essas configurações é só fazer o seguinte:


Dim _Config As Configuration = System.Configuration.ConfigurationManager.GetSection("ExemploConfig")

Dim _SaveLog As Boolean = _Config.SaveLog


É possível também criar coleções de configurações: para isto, é necessário criar uma classe para lidar com a coleção e uma outra classe que definirá os itens dessa coleção, por exemplo, para adicionarmos uma coleção de módulos dentro do nosso exemplo anterior, ficaria assim:

Arquivo XML:


<!-- O trecho a seguir configura as secões customizadas do arquivo de configurações -->
<configSections>
<section name="ExemploConfig" type="ExemploConfiguracao.Configuration, ExemploConfiguracao"/>
</configSections>

<!-- A Seguir estão as configurações armazenadas no trecho configurado anteriormente -->
<ExemploConfig SaveLog="True">
<Modules>
<add ModuleName="Teste1" ExtractQuery="Select * From Tabela" />
<add ModuleName="Teste2" />
</Modules>
</ExemploConfig>


Classe Configuration:


Public Class Configuration
Inherits System.Configuration.ConfigurationSection

<System.Configuration.ConfigurationProperty("SaveLog", IsRequired:=True)> _
Public ReadOnly Property SaveLog() As Boolean
Get
Return Convert.ToBoolean(MyBase.Item("SaveLog"))
End Get
End Property

<System.Configuration.ConfigurationProperty("Modules", IsRequired:=False)> _
Public ReadOnly Property Modules() As ModuleConfigurationCollection
Get
Return MyBase.Item("Modules")
End Get
End Property
End Class


Classe que controlará a coleção:

<System.Configuration.ConfigurationCollection(GetType(ModuleConfiguration), AddItemName:="add", ClearItemsName:="clear")> _
Public Class ModuleConfigurationCollection
Inherits System.Configuration.ConfigurationElementCollection

Protected Overloads Overrides Function CreateNewElement() As System.Configuration.ConfigurationElement
Return New ModuleConfiguration()
End Function

Protected Overrides Function GetElementKey(ByVal element As System.Configuration.ConfigurationElement) As Object
Return DirectCast(element, ModuleConfiguration).ModuleName
End Function

Default Public Overloads ReadOnly Property Item(ByVal Index As Int32) As ModuleConfiguration
Get
Return BaseGet(Index)
End Get
End Property
End Class


Classe que representa os itens da coleção:


Public Class ModuleConfiguration
Inherits System.Configuration.ConfigurationElement

<System.Configuration.ConfigurationProperty("ModuleName", IsRequired:=True, IsKey:=True)> _
Public ReadOnly Property ModuleName() As String
Get
Return Me.Item("ModuleName")
End Get
End Property

<System.Configuration.ConfigurationProperty("ExtractQuery")> _
Public ReadOnly Property ExtractQuery() As String
Get
Return Me.Item("ExtractQuery")
End Get
End Property
End Class


Pesquisando mais afundo você encontrará parâmetros que podem ser configurados nas propriedades da classe de fachada que implementam validação sobre os dados inseridos, além da validação básica que há no exemplo (IsRequired:=True).

Acredito que esta abordagem para configuracões de aplicativos pode trazer benefícios na fase de implantação, pois é possível criar um ConfigSection mais intuitivo para quem irá realizar a configuração do aplicativo (na maioria das vezes quem realiza esta configuração não é o desenvolvedor). Esta abordagem também torna mais simples a tarefa de mover as configurações para um arquivo XML diferente do web.config ou do app.config.

Baixe o exemplo acima completo para o Visual Studio 2008: Download

terça-feira, 29 de abril de 2008

Desenvolvimento de Aplicações Web Utilizando Castle ActiveRecord

Olá! Neste post pretendo apresentar o framework de persistência de dados Castle ActiveRecord, com o qual tenho desenvolvido algumas aplicações nos úlimos meses.
Com ele, o desenvolvimento de software pode se tornar muito mais simples e rápido, diminuindo a quantidade de código que o desenvolvedor tem que produzir e facilitando o mapeamento entre o mundo relacional da maioria dos SGBDs comerciais de hoje para o mundo dos objetos, das nossas aplicações .Net. Porém, a desvantagem fica por conta da menor flexibilidade para manipular os dados através dele.

Quem já conhece ou utiliza o nhibernate, o Castle ActiveRecord pode ajudar facilitando a configuração do nhibernate. Com o ActiveRecord não há necessidade de configurar xml para criar os mapeamentos do nhibernate!

A primeira diferença entre desenvolver uma aplicação sem utilizar nenhum framework de persistência de dados e desenvolver uma aplicação utilizando o Castle ActiveRecord é a arquitetura das camadas do software, numa aplicação comum, teríamos as seguintes camadas:
  • Camada de Apresentação (Páginas ASP.Net, por exemplo, é o que o usuário vê)
  • Camada de Controle (As classes que controlam a Apresentação, como o code-behind das páginas ASP.Net e fazem com que aquilo que o usuário vê realize operações)
  • Camada de Negócio (Com os procedimentos do negócio, contém as operações seguindo as regras estipuladas nos requisitos)
  • Camada de Transferência de Dados (também conhecida como Value Objects, é onde temos os principais objetos do sistema)
  • Camada de Acesso à Dados (nela, os dados gerados na aplicação são enviados ao SGBD, e os dados deste são recuperados para serem utilizados na aplicação - geralmente aqui acontece a transformação da forma relacional para a forma dos objetos)
  • Camada de Dados (normalmente dentro do SGBD, programada com Stored Procedures)
Em projetos simples, podemos encontrar uma simplificação da arquitetura acima que dispensa a camada de negócio, que ficaria assim:
  • Camada de Apresentação
  • Camada de Controle
  • Camada de Transferência de Dados
  • Camada de Acesso a Dados
  • Camada de Dados
Já em projetos utilizando o Castle ActiveRecord, teríamos a seguinte arquitetura:
  • Camada de Apresentação
  • Camada de Controle
  • Camada de Modelo (esta nova camada fará o trabalho das 3 últimas camadas do último exemplo, com o mínimo de programação)
Esta arquitetura é conhecida como MVC (Model-View-Control) ou Modelo-Visualização-Controle. De início já notamos que temos duas camadas a menos, só isso já poupa um bocado de desenvolvimento.

Dentro da camada de Modelo, que é onde ficará o código que utilizará o Castle ActiveRecord, acontecerá o seguinte:
As classes serão feitas da mesma forma como eram feitas na Camada de Transferência de Dados, porém todas as classes deverão herdar a classe ActiveRecordBase, que se encontra no framework. A classe deverá, também, ser configurada através de um parâmetro, indicando qual tabela do SGBD aquela classe representa.
As propriedades das classes deverão ser configuradas indicando a qual atributo da tabela elas se referem e se ela é chave primária, um relacionamento com outra tabela, etc.

Exemplo simples de classe em VB (.Net Framework 2.0):

Para a seguinte tabela:

Create Table tbFuncionario(
ID Int,
Nome VarChar(100),
Matricula Char(6))

Teríamos a seguinte classe:


Imports Castle.ActiveRecord

<Activerecord("tbFuncionario")> _
Public Class Funcionario
Inherits ActiveRecordBase(Of Funcionario)

Private _ID As Integer
Private _Nome As String
Private _Matricula As String

<PrimaryKey("ID")> _
Public Property ID As Integer
Get
Return _ID
End Get
Set (ByVal Value As Integer)
_ID = Value
End Set
End Property

<Property("Nome")> _
Public Property Nome As String
Get
Return _Nome
End Get
Set (ByVal Value As String)
_Nome = Value
End Set
End Property

<Property("Matricula")> _
Public Property Matricula As String
Get
Return _Matricula
End Get
Set (ByVal Value As String)
_Matricula= Value
End Set
End Property
End Class


Pronto! Com a classe acima já é possível fazer Select, Insert, Update e Delete na tabela tbFuncionario!

Como?

O Castle ActiveRecord (através do nhibernate) gerará os códigos SQL em runtime para fazer as operações no SGBD. A segunda grande vantagem disso (a primeira vantagem foi a economia de código) é que apenas mudando um parâmetro na configuração do nhibernate, a aplicação poderá utilizar SQL Server, Oracle, ou qualquer outro SGBD suportado pelo nhibernate.

Veja mais informações sobre o Castle ActiveRecord e outros framewors do projeto Castle em:
http://www.castleproject.org/

Veja mais informações sobre o nhibernate em:
http://www.nhibernate.org/

Seja Bem Vindo!

Seja bem-vindo ao meu recém-criado blog!!! Pretendo expor neste espaço dicas, novidades e opiniões sobre tecnologia e desenvolvimento de software.
Sou estudante universitário, desenvolvedor ASP.Net com 4 anos de experiência e estou trabalhando atualmente em projetos voltados às áreas de Marketing, Endomarketing e e-commerce.
Espero trazer informações úteis e ajudar a todos compartilhando soluções dos problemas que eu enfrentar no dia-a-dia.