2009-05-06 11 views
0

Je joue avec la génération de classe (une classe pour une table - héritage, etc. à ne pas considérer pour l'instant ...). Donc, j'ai copié sans vergogne de here le code Reflection.Emit. Retravaillé pour être généré par table dans une base de données donnée et créé les fichiers avec l'appel de lot suivant dans le dossier bin du projet: pour/f "tokens = *" %% i in ('dir * .xsd/b') "C: \ Programmes \ Microsoft SDKs \ Windows \ v6.0A \ bin \ xsd.exe" -c -l: C# -n: BusinessObjects% iQuels sont les pièges à attendre de la génération de classes à partir des tables de base de données à l'aide des fichiers Reflection.Emit et xsd?

Jusque là tout va bien. L'idée est chaque fois qu'une nouvelle version db arrive pour régénérer les classes et les copier dans le "vrai projet" (je n'ai pas besoin d'une génération d'exécution) et j'aimerais aussi profiter d'Intellisense. Quels pièges, difficultés et problèmes peuvent découler de ce type d'approche, de meilleures suggestions pour ces exigences vaguement décrites?!

Voici le code Génération de l'application de la console en créant les assemblages:

using System; 
    using System.Collections.Generic; 
    using System.Text; 
    using log4net; 
    using log4net.Config; 
    using System.Data; 
    using System.Data.SqlClient; 
    using System.Threading; 
    using System.Reflection; 
    using System.Reflection.Emit; 

    namespace GenerateAssemblies 
    { 

     class Program 
     { 

     private static readonly ILog logger = 
      LogManager.GetLogger (typeof (Program)); 


     static void Main (string[] args) 
     { 
      DOMConfigurator.Configure(); //tis configures the logger 
      logger.Debug ("APP START"); 

      DataTable dtTables = Program.GetTablesFromDb ("POC") ; 
      foreach (DataRow dr in dtTables.Rows) 
      { 
      string strTableName = dr[0].ToString() ; 
      CodeEmitGeneratingAssemblies.DllGenerator.WriteXmlAndTxtFileOutOfDataTableByName ( strTableName); 
      CodeEmitGeneratingAssemblies.DllGenerator.CreateAssembly (strTableName); 
      } 


      Console.WriteLine (" Should have now all the dll's "); 
      Console.ReadLine(); 
     } //eof method 



     static DataTable GetTablesFromDb (string strDbName) 
     { 


      DataTable dt = new DataTable ("tables"); 

      string connectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=" + strDbName + ";Data Source=ysg"; 

      using (SqlConnection connection = new SqlConnection (connectionString)) 
      { 
      SqlCommand command = connection.CreateCommand(); 

      command.CommandText = string.Format ("SELECT name from sys.tables"); 

      connection.Open(); 
      dt.Load (command.ExecuteReader (CommandBehavior.CloseConnection)); 
      } 
      return dt; 
     } //eof method 


     } //eof class 


    namespace CodeEmitGeneratingAssemblies 
    { 
     public class DllGenerator 
     { 
     private static readonly ILog logger = 
      LogManager.GetLogger (typeof (DllGenerator)); 




     public static void WriteXmlAndTxtFileOutOfDataTableByName (string strDataTableName) 
     { 
      DOMConfigurator.Configure(); //tis configures the logger 
      DataTable tableData = new DataTable (strDataTableName); 

      string connectionString = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=POC;Data Source=ysg"; 

      using (SqlConnection connection = new SqlConnection (connectionString)) 
      { 
      SqlCommand command = connection.CreateCommand(); 

      command.CommandText = string.Format ("SELECT * FROM [" + strDataTableName + "]"); 
      logger.Debug ("command.CommandText is " + command.CommandText); 
      connection.Open(); 
      tableData.Load (command.ExecuteReader (CommandBehavior.CloseConnection)); 
      } 

      tableData.WriteXml (strDataTableName + ".xml"); 
      tableData.WriteXmlSchema (strDataTableName + ".xsd"); 
     } //eof method 


     public static void CreateAssembly (string strDataTableName) 
     { 
      AppDomain currentDomain = Thread.GetDomain(); 

      AssemblyName myAssemblyName = new AssemblyName (); 
      myAssemblyName.Name = strDataTableName; 

      AssemblyBuilder builder = currentDomain.DefineDynamicAssembly (
           myAssemblyName, 
           AssemblyBuilderAccess.RunAndSave); 

      builder.AddResourceFile ("TableXml", strDataTableName + ".xml"); 
      builder.AddResourceFile ("TableXsd", strDataTableName + ".xsd"); 

      builder.Save (strDataTableName + ".dll"); 
     } 

     } //eof class 
    } //eof namespace 

    } //eof namespace 

Répondre

1

Vous obtenez tous les problèmes d'utilisation (relationnelle) base de données axée sur oo conception:

  • pas assez abstraction , pas d'héritage et pas de construction d'ADTs;
  • classes avec trop de responsabilités;
  • comportement au mauvais endroit;
  • aucun moyen utilisable pour gérer les aspects temporels.

Je préfère travailler dans l'autre sens. Du modèle oo à la base de données

[edit] Vous pourriez essayer de faire fonctionner un modèle hybride. Aller de DB à OO pour une partie de l'application, et l'inverse pour une autre partie. Cela vous permet de refactoriser lentement et de migrer vers OO-> DB.

+0

Je suis d'accord avec vous ... Mon problème est que le fait db existe déjà si je dois adopter pour lui .. –

0

Duh ... oneliner avec Subsonic:

sonic generate /override /server HOMIE /db BlogEngine /userid OMMITED /password OMMITED /out C:\code\out /generatedNamespace BlogEngine.Core.Providers.SubSonic /stripTableText be_