Sono nelle prime fasi della creazione di un nuovo progetto di sviluppo e non sono sicuro di come impostare la mia strategia di accesso al database. Userò Visual Studio 2012 e utilizzerò .NET 4.5 e SQL Server 2008 o 2012.Una combinazione di Entity Framework, Dapper e SSDT?
Ciò di cui non sono sicuro è se utilizzare Entity Framework e, in caso affermativo, in quale misura. Dato che leggere i dati dal database e quindi elaborarli sarà il lavoro principale per questa applicazione, le prestazioni delle query saranno importanti. So che EF5 è molto meglio di EF4.x a tale riguardo, ma non è l'overhead EF intrinseco di cui sono più preoccupato (anche se qualcosa come Dapper è ancora almeno due volte più veloce) ma più la pigrizia che ti offre come sviluppatore, perché interrogare troppo è così facile con LINQ. Quindi voglio che le semplici query SQL siano il modo principale per recuperare i dati.
Tuttavia, ciò che mi mancherà di più di EF è:
- Compile controllo interrogazione tempo.
- Cambio di tracciamento.
- Codice prima sviluppo.
- Unità di modello di lavoro.
Posso vivere senza il rilevamento delle modifiche, di solito non è così difficile determinare cosa è nuovo o aggiornato.
Quello che voglio è che gli sviluppatori di questo progetto non debbano scherzare con i progettisti di tabelle, ma che possano semplicemente scrivere POCO. Quindi, per questo, apprezzo molto il primo approccio al codice di EF. Con questo, uno sviluppatore può clonare il codice sorgente, chiamare update-database
e avere un database locale funzionante. È qualcosa che ha funzionato bene per me in passato.
Un'altra cosa che per me è molto importante è un'unità di modello di lavoro o l'atomicità di inserti e aggiornamenti. Voglio mettere in coda tutte le modifiche e avere un singolo punto in cui chiamo SaveChanges
. Con librerie come DapperExtensions
, si ottiene un metodo Insert
, ma effettuerà immediatamente la chiamata al database. Puoi renderlo atomico avvolgendo una transazione intorno ad esso, ma non è lo stesso che fare la coda. Quindi dovrei preparare una specie di meccanismo di accodamento per questo.
Per il controllo della query del tempo di compilazione, considero l'utilizzo di SQL Server Data Tools (SSDT). Le query sarebbero stored procedure (per evitare grossi blob di stringa di query nel codice C#) e utilizzando SSDT questi possono essere controllati in fase di compilazione. Un altro vantaggio di SSDT è che è possibile distribuire le stored procedure da Visual Studio a un database di destinazione. E, soprattutto, gli script SQL per questi vivrebbero nel controllo del codice sorgente.
Quindi, con questo, la mia soluzione sarebbe fondamentalmente consistono di tecnologie di accesso ai dati a tre:
Entity Framework
- sarebbe responsabile per la creazione del database da datamodels POCO.
- Sarebbe utilizzato per inserire/aggiornare i dati attraverso la sua unità di modello di lavoro. Un avvertimento sarebbe che si dovrebbe prima di
Attach
entità che sono state recuperate tramite SQL al contesto.
SSDT
- sarebbero stati utilizzati per verificare gli script SQL in fase di compilazione.
- Permette agli script di vivere in Git.
- Distribuire le cose che EF non può distribuire nel database.
Dapper/altra Micro ORM
- sarebbe stato utilizzato per recuperare i dati
non posso fare a meno di sentire questo è un po 'di una soluzione di Frankenstein in cui io uso vari frammenti di tutto. Inoltre, non sono ancora sicuro che SSDT ed EF lavoreranno insieme in un modo piacevole. Questo rapido esempio sembra funzionare bene però:
// Combo of Dapper, EF and a stored proc that was published through SSDT
static void Main(string[] args)
{
var connectionString = ConfigurationManager
.ConnectionStrings["DbDataContext"].ConnectionString;
using (var conn = new SqlConnection(connectionString))
using (var ctx = new DbDataContext())
{
conn.Open();
var product = conn.Query<Product>("GetProduct",
commandType: CommandType.StoredProcedure).First();
ctx.Products.Attach(product);
var order = new Order
{
Product = product
};
ctx.Orders.Add(order);
ctx.SaveChanges();
}
}
Questo approccio sembra funzionare, ma è anche complicato. Ma se rinuncio all'SSDT, mi mancherà il controllo del tempo di compilazione di SQL, se rinuncio a Entity Framework, mi mancheranno gli inserti in codice e più facili e se rinuncio all'analisi SQL diretta mi mancherà fuori su una grande fetta di prestazioni.
Esiste un'alternativa che sto con vista? In caso contrario, qual è l'approccio migliore qui?
"la pigrizia che vi offre come sviluppatore" - E 'il vostro lavoro per non essere pigro; EF offre ingegneria per prestazioni perfette. – millimoose
Sì, ma non utilizzando LINQ. Dovrai andare giù a SQL raw e quindi è ancora solo la metà della velocità del semplice ADO.NET/Dapper (http://goo.gl/ctD9f). Potrebbe anche andare con Dapper per le domande. Tuttavia, voglio evitare grossi blocchi anonimi di stringhe per le query nel codice C#, motivo per cui ho guardato a SSDT per spostarlo dal codice. – JulianR
Ok, ma questa è una questione di sovraccarico del framework che è al di fuori del controllo degli sviluppatori. Il mio punto era semplicemente che "offre pigrizia" non è una buona ragione per scegliere o non scegliere una tecnologia. Se sei disposto a scambiare spese generali per la "profondità" di ORM, hai ancora la possibilità di evitare i problemi di prestazioni causati dal problema di selezione di N + 1. (Questo problema ha anche un impatto significativo sulle prestazioni, è altrettanto facile da incontrare in SQL raw e molto più difficile da risolvere perché scrivere enormi uberqueries è più difficile in SQL che in LINQ.) – millimoose