quarta-feira, 14 de outubro de 2009

Linq to SQL - Trabalhando com Procedures Dinâmicas

Fala, galera!!

Hoje estarei publicando uma espécie de "workaround" para uma limitação do Linq to SQL.
O LINQ nos permite trabalhar com stored procedures, gerando métodos de acesso às mesmas.
Quando criamos uma procedure que utiliza uma query "estática" o LINQ nos permite definir qual será o retorno da mesma: Auto-Generated ou algum objeto(tabela) do LINQ.

Mas quando trabalhamos com Queries dinâmicas o LINQ entende que o retorno da procedure é sempre um Inteiro (integer). Como contornar este problema?

Na verdade é bem simples. Basta estendermos a classe do LINQ.

O seu arquivo DBML possui 3 arquivos relacionados. o .dbml, o .designer.vb e o .vb.

Jamais altere o .designer.vb, pois este arquivo é gerado automaticamente a cada modificação no LINQ.
Ou seja, todas as suas modificações manuais são perdidas a cada modificação.

Para fazer as modificações, utilize o arquivo .vb.

Segue como deve ficar o seu aquivo .vb


Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Linq
Imports System.Data.Linq.Mapping
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Reflection
Imports System.ComponentModel.DataAnnotations
Imports Catalyst.ComponentModel.DataAnnotations

Namespace NomeProjetoDataContext


    Partial Public Class NomeProjeto
      <FunctionAttribute(Name:="dbo.procBuscarNoticias")> _
       Public Function procBuscarNoticias(<Parameter(Name:="Titulo", DbType:="VarChar(200)")> ByVal titulo As String, <Parameter(Name:="Resumo", DbType:="VarChar(500)")> ByVal resumo As String, <Parameter(Name:="DataCadastro", DbType:="VarChar(20)")> ByVal dataCadastro As String, <Parameter(Name:="CodCategoria", DbType:="Int")> ByVal codCategoria As System.Nullable(Of Integer), <Parameter(Name:="IndDestaque", DbType:="Int")> ByVal indDestaque As System.Nullable(Of Integer), <Parameter(Name:="IndAtiva", DbType:="Int")> ByVal indAtiva As System.Nullable(Of Integer)) As ISingleResult(Of Noticia)
            Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo), titulo, resumo, dataCadastro, codCategoria, indDestaque, indAtiva)
            Return CType(result.ReturnValue, ISingleResult(Of Noticia))
        End Function
End Class

End Namespace

O código acima irá instanciar uma procedure que receberá alguns parâmetros e montará uma query dinâmica com base nesses parâmetros.
Definimos manualmente que o resultado desta procedure será um objeto do tipo "Noticia".

Apenas para constar: A estensão desta classe em um arquivo separado só pode ser feita graças ao conceito de Partial Class. O Partial Class permite que uma mesma classe possa estar distribuída em arquivos diferentes. Permitindo uma maior organização do seu código.

Um abraço e até a próxima!!

Nenhum comentário:

Postar um comentário