segunda-feira, 12 de outubro de 2009

ASP.Net Dynamic Data - Gerando as classes de Metadados automaticamente

Fala, galera!!

O ASP.Net Dynamic Data permite que estendamos as classes de metadados das tabelas do banco de dados para que possamos fazer algumas customizações nas telas. Como: Aplicar regras de validação, formatar saída de dados, alterar o nome de exibição dos campos, etc.

Para que possamos estender essas classes, devemos codificar manualmente uma a uma.
Imagine o trabalho que isso daria em uma base de dados com muitas tabelas.

Para evitar esse trabalho manual, podemos automatizar a criação dos arquivos destas classes.
Segue o código:


Private Sub GerarAquivosDeMetadados()
        For i = 0 To MetaModel.Default.VisibleTables.Count - 1
            Dim arquivo As New Componente.Text.Controller
            Dim caminho As String = "c:\EnderecoDoProjeto" & MetaModel.Default.VisibleTables(i).EntityType.Name & "Partial.vb"
            Dim classes As String = CarregarImports()
            Dim conteudo As New StringBuilder
            conteudo.Append(classes & vbCrLf & "Namespace ManutencaoDataContext" & vbCrLf)
            If Not arquivo.FileExists(caminho) Then
                arquivo.OpenNewFile(caminho)
                conteudo.Append(vbTab & "<MetadataType(GetType(" & MetaModel.Default.VisibleTables(i).EntityType.Name & "_Metadata))> _" & vbCrLf)
                conteudo.Append(vbTab & "Partial Public Class " & MetaModel.Default.VisibleTables(i).EntityType.Name & vbCrLf)
                conteudo.Append(vbTab & "End Class" & vbCrLf & vbCrLf)
                conteudo.Append(vbTab & "Class " & MetaModel.Default.VisibleTables(i).EntityType.Name & "_Metadata" & vbCrLf & vbCrLf)
                For j = 0 To MetaModel.Default.VisibleTables(i).Columns.Count - 1
                    conteudo.Append(vbTab & vbTab & "Private _" & MetaModel.Default.VisibleTables(i).Columns(j).Name & " as " & IIf(InStr(MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString, "Int32") > 0, "Integer", MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString) & vbCrLf)
                Next
                conteudo.Append(vbCrLf)
                For j = 0 To MetaModel.Default.VisibleTables(i).Columns.Count - 1
                    conteudo.Append(vbTab & vbTab & "Public Property " & MetaModel.Default.VisibleTables(i).Columns(j).Name & "() as " & IIf(InStr(MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString, "Int32") > 0, "Integer", MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString) & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & "Get" & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & vbTab & "Return _" & MetaModel.Default.VisibleTables(i).Columns(j).Name & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & "End Get" & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & "Set(ByVal value As " & IIf(InStr(MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString, "Int32") > 0, "Integer", MetaModel.Default.VisibleTables(i).Columns(j).TypeCode.ToString) & ")" & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & vbTab & "_" & MetaModel.Default.VisibleTables(i).Columns(j).Name & " = Value" & vbCrLf)
                    conteudo.Append(vbTab & vbTab & vbTab & "End Set" & vbCrLf)
                    conteudo.Append(vbTab & vbTab & "End Property" & vbCrLf & vbCrLf)
                Next
                conteudo.Append(vbTab & "End Class" & vbCrLf)
                conteudo.Append("End Namespace")
                arquivo.WriteLine(conteudo.ToString)
                arquivo.CloseFile()
                arquivo = Nothing
            End If
        Next
    End Sub


Private Function CarregarImports() As String
    Dim conteudo As New StringBuilder
    conteudo.Append("Imports System" & vbCrLf)
    conteudo.Append("Imports System.Collections.Generic" & vbCrLf)
    conteudo.Append("Imports System.ComponentModel" & vbCrLf)
    conteudo.Append("Imports System.Data" & vbCrLf)
    conteudo.Append("Imports System.Data.Linq" & vbCrLf)
    conteudo.Append("Imports System.Data.Linq.Mapping" & vbCrLf)
    conteudo.Append("Imports System.Linq" & vbCrLf)
    conteudo.Append("Imports System.Linq.Expressions" & vbCrLf)
    conteudo.Append("Imports System.Reflection" & vbCrLf)
    conteudo.Append("Imports System.ComponentModel.DataAnnotations" & vbCrLf)
    conteudo.Append("Imports Catalyst.ComponentModel.DataAnnotations" & vbCrLf)
    conteudo.Append("Imports System.Web.DynamicData" & vbCrLf)
    Return conteudo.ToString
End Function


OBS: Utilizei um componente que eu mesmo desenvolvi para fazer toda a manipulação do arquivo (criar, escrever, verificar a existência, etc.).
Este componente encapsula todas os namespaces e métodos do .net necessários para a manipulação de arquivos.
Quando você utilizar este código, deve substituir a chamada do meu componente pela chamada das classes do .net diretamente para a manipulação dos arquivos.

Normalmente, insiro o código acima no arquivo Default.aspx do ADD e executo o método GerarArquivosDeMetaDados no início da codificação.

Este código irá gerar fisicamente todas as classes de metadados que preciso no meu projeto.
Mas ainda é preciso incluí-las no projeto.

Vá ao solution explorer, clique na opção para exibir todos os arquivos.
As classes serão exibidas com um ícone branco. Clique com o botão direito do mouse nas classes e selecione a opção "Include in Project".

Pronto. Suas classes estão geradas e incluídas no projeto. Agora é só customizar.

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

Nenhum comentário:

Postar um comentário