posts - 315, comments - 268, trackbacks - 15

My Links

News

View Pietro Libro's profile on LinkedIn

DomusDotNet
   DomusDotNet

Pietro Libro

Tag Cloud

Article Categories

Archives

Post Categories

Blogs amici

Links

EF 4.0 + MEF (+ POCO) = “Database Switching”

E’ da un po’ di tempo che avrei voluto scrivere questo post, ma tra una cosa e l’altra…meglio tardi che mai. Una delle novità di .NET 4.0 che utilizzo (quasi) quotidianamente è sicuramente EF 4.0 (a dire il vero anche la versione precedente), ma il supporto POCO è tutta un’altra storia. Tra le altre novità , sicuramente MEF (Managed Extensibility Framework) che affianca MAF (Manager Add-In Framework) presente dalla versione 3.5 di .NET. Per chi volesse approfondire questi concetti ricordo dei post di Federico in merito. Veniamo a noi, il titolo, è “un’equazione” il cui risultato vuole rappresentare uno dei scenari seguenti:  un’applicazione che deve poter utilizzare due RDBMS diversi per eseguire lo storage delle informazioni (ad esempio come server principale Microsoft SQL Server e come secondario MySQL o viceversa),  un’applicazione che deve eseguire una scrittura (contemporanea) su database diversi,  un’applicazione che deve scegliere quale database utilizzare secondo delle condizioni iniziali (configurazione) o ancora un’applicazione che a “caldo” possa “selezionare” quale base di dati utilizzare. Sicuramente possono essere considerati molti altri scenari, ma spero di aver reso l’idea della problematica. Per ogni scenario, possono esistere numerose soluzioni, secondo della tecnologia impiegata. Nel post, prendo in considerazione i due framework precedentemente menzionati e assemblati per creare un’applicazione che esegue una serie di INSERT, UPDATE e DELETE (via Entity Framework ovviamente) utilizzando  una connessione ad un database Microsoft SQL Server o una connessione ad un database MySQL, utilizzando il supporto POCO. Il Layer Diagrams sottostante rappresenta la dipendenza tra i tre layers (e relativi progetti) presenti della soluzione VS 2010 allegata:

image

Il Data Layer è composto da due progetti tra loro indipendenti: DBCompany.Storage.MySQL e DBCompany.Storage.SQLServer il cui Entity Data Model contiene due entità Employee e Role  ed un’associazione molti a molti:

image 

In ognuno dei progetti è presente il codice seguente (nell’esempio la versione MySQL):

   1: [Export(typeof(IDBCompanyEntities))]
   2:    public partial class MySQLDataConnectorEntities : ObjectContext, IDBCompanyEntities 
   3:    {
   4:        public const string ConnectionString = "name=MySQLDataConnectorEntities";
   5:        public const string ContainerName = "MySQLDataConnectorEntities";
   6:    
   7:        #region Constructors
   8:    
   9:        public MySQLDataConnectorEntities()
  10:            : base(ConnectionString, ContainerName)
  11:        {
  12:            this.ContextOptions.LazyLoadingEnabled = true;
  13:        }
  14:    
  15:        public MySQLDataConnectorEntities(string connectionString)
  16:            : base(connectionString, ContainerName)
  17:        {
  18:            this.ContextOptions.LazyLoadingEnabled = true;
  19:        }
  20:    
  21:        public MySQLDataConnectorEntities(EntityConnection connection)
  22:            : base(connection, ContainerName)
  23:        {
  24:            this.ContextOptions.LazyLoadingEnabled = true;
  25:        }
  26:    
  27:        #endregion
  28:    
  29:        public string StorageVersion()
  30:        {
  31:            return "MYSQL";
  32:        }
  33:    
  34:        #region ObjectSet Properties
  35:    
  36:        public ObjectSet<Employee> Employees
  37:        {
  38:            get { return _employees  ?? (_employees = CreateObjectSet<Employee>("Employees")); }
  39:        }
  40:        private ObjectSet<Employee> _employees;
  41:    
  42:        public ObjectSet<Role> Roles
  43:        {
  44:            get { return _roles  ?? (_roles = CreateObjectSet<Role>("Roles")); }
  45:        }
  46:        private ObjectSet<Role> _roles;
  47:  
  48:        #endregion
  49:    }

Che concretizza l’ObjectContext specializzato, il quale a sua volta implementa l’interfaccia IDBCompanyEntities “necessaria” per avere il supporto MEF:

   1: public interface IDBCompanyEntities 
   2: {
   3:     ObjectSet<Employee> Employees { get; }
   4:     ObjectSet<Role> Roles { get; }
   5:     int SaveChanges();
   6:     int SaveChanges(SaveOptions options);
   7:     string StorageVersion();
   8: }

Il progetto DBCompany.BusinessObjects contiene oltre alla suddetta interfaccia (la quale potrebbe essere inserita in un progetto contenente solo i Contracts) anche la definizione degli oggetti POCO:

image

Il progetto di test  è un’applicazione console che non ha nessun riferimento al Data Layer, ma solo al Domain Layer. In esecuzione si presenta in questo modo:

image

Prima di procedere “chiede” se si vuole utilizzare il data provider per Microsoft SQL Server o MySQL e secondo che venga premuto il tasto “S” (SQL Server) o un altro tasto, parte una piccola demo che esegue delle scritture sul database scelto. Nella figura sottostante un esempio di esecuzione con il server MySQL:

image

Inizialmente ho utilizzato come data provider per MySQL la versione trial di DotConnect per MySQL , ma nella versione allegata  ho utilizzato la versione 6.3.3(Beta) del data provider fornito direttamente dal sito di MySQL (occorre la registrazione per effettuare il download). In questo contesto MEF è “configurato” per caricare tutti gli assembly presenti nella directory specificata nel codice e permettere all’utente (in questo caso manualmente) quale data provider utilizzare, ma potrebbe essere configurato per considerare un solo add-in per volta. Una critica può essere sollevata dal fatto di dover mantenere aggiornati due Entity Data Model (praticamente) uguali, mentre se ne potrebbe utilizzare solo uno, utilizzando una terzo progetto libreria. Lo scopo del post però non è quello di voler rappresentare un’ottimizzazione algoritmica, ma quella di voler proporre una soluzione ad un problema più o meno comune utilizzando gli ultimi strumenti messi a disposizione dal .Net Framework 4.0.

Nel codice allegato sono presenti gli script per la creazione dei due database di test (ovviamente è necessario che le stringhe di connessione siano configurare in modo opportune).

Download File - ZipSource

Print | posted on martedì 17 agosto 2010 21:55 |

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET