Entity Framework & SQL Server - Better Together Alberto Dallagiacoma @albertodall E-Mail: [email protected] Blog: http://blogs.ugidotnet.org/alby November 28°, 2015 #sqlsatParma #sqlsat462 Sponsors November 28°, 2015 #sqlsatParma #sqlsat462 Organizers getlatestversion.it November 28°, 2015 #sqlsatParma #sqlsat462 Alberto Dallagiacoma | @albertodall • • • • November 28°, 2015 #sqlsatParma #sqlsat462 Agenda – Richiedere troppi dati – Scrivere query non in termini di “Set” – Generazione dello schema del database a partire dal modello ad oggetti November 28°, 2015 #sqlsatParma #sqlsat462 It’s always a matter of T-SQL – Scriviamo la nostra query T-SQL e la inviamo al database. – La query passa all’Execution Engine o Query Optimizer per stabilire il miglior piano di esecuzione possibile. o Ritorna i risultati nel minor tempo possibile. November 28°, 2015 #sqlsatParma #sqlsat462 Utilizzare un O/RM – Introduciamo un layer in più, perché il codice T-SQL viene generato dall'O/RM. – L'origine del codice T-SQL non è più un modello relazionale, ma un modello ad oggetti. – La query (LINQ, EntitySQL…) che scriviamo può essere molto “espressiva”, ma può produrre codice T-SQL poco performante. o Scriviamo un buon codice applicativo, ma che ha scarse prestazioni a livello di database. – Dobbiamo mettere in condizione l'O/RM di generare il miglior codice T-SQL possibile. November 28°, 2015 #sqlsatParma #sqlsat462 Ma allora… Perché usarlo? – Linguaggio familiare allo sviluppatore (C#, LINQ…) – Strong typing. – Focus sulla business logic e non sullo storage. – T-SQL è poco espressivo, e non ha un compilatore a supporto. – Migliore esperienza di debugging. – Diventa semplice migrare l’applicazione da un RDBMS ad un altro. November 28°, 2015 #sqlsatParma #sqlsat462 1 - Richiedere troppi dati productsQuery = customersQuery = customersQuery – Page Life Expectancy bassa – Latenza sull’I/O e sull’infrastruttura – Indici non sfruttati November 28°, 2015 #sqlsatParma #sqlsat462 DEMO – Filtrare client side – Filtrare server side – Projections November 28°, 2015 #sqlsatParma #sqlsat462 Caricare troppi dati: considerazioni • Evitare di richiedere la totalità dei dati per poi fare filtri client side. • Eseguire lato server i filtri sui dati; la presenza di indici dedicati favorisce queste operazioni. • Utilizzare le projections per richiedere al database le sole colonne che servono. November 28°, 2015 #sqlsatParma #sqlsat462 2 - Pensare le query non in termini di “Set” – Lavorare “record per record” è inefficiente (cursori ?) – Con un O/RM si ha il problema delle “N+1 Select” – Aprire una connessione – Verificare i permessi dell’utente – Passare la query all’Execution Engine/Optimizer – Eseguire le istruzioni richieste November 28°, 2015 #sqlsatParma #sqlsat462 DEMO – Navigazione di una child collection – Stabilire un “fetch plan” adeguato November 28°, 2015 #sqlsatParma #sqlsat462 Non pensare in termini di “Set”: considerazioni • Evitare di eseguire loop sui risultati ritornati dall’O/RM. • Stabilire un fetch plan adatto per ogni query/caso d’uso. • In caso di dubbi, eseguire sempre la profilazione del codice SQL generato. November 28°, 2015 #sqlsatParma #sqlsat462 3 – Creare il DB dal modello “Code First” – Diventa facile ricreare lo stesso schema su storage (RDBMS) diversi. – Molto utile per eseguire gli “integration test”. – Il type system del CLR deve essere "mappato" sul type system del RDBMS sottostante. Le stringhe devono essere char, varchar o nvarchar? o Il tipo Boolean deve essere rappresentato come “True/False” o come “0/1”? o – L'applicazione non è l'unica "entità" che usa il database. Repliche o Manutenzioni o Backup o Qualità del dato o November 28°, 2015 #sqlsatParma #sqlsat462 DEMO – Data Annotations – Fluent API – Integration test November 28°, 2015 #sqlsatParma #sqlsat462 Database “Code First”: considerazioni • Lo sviluppatore deve comunque fare un’analisi sui tipi di dato richiesti. • E’ un buon modo per fare prototipizzazione del database e integration testing. • La configurazione finale del database per l’ambiente di produzione va fatta in collaborazione con il DBA. November 28°, 2015 #sqlsatParma #sqlsat462 Debugging e profiling – Se usato direttamente in produzione, impatta pesantemente sulle performance – Utile per mostrare direttamente l’output del codice SQL generato – Proprietà DbContext.Log – Interfaccia IDbCommandInterceptor November 28°, 2015 #sqlsatParma #sqlsat462 DEMO – IQueryable.ToString() – Proprietà DbContext.Log e uso di un logger personalizzato – Implementazione di un IDbCommandInterceptor November 28°, 2015 #sqlsatParma #sqlsat462 Considerazioni “server side” • SELECT * FROM [dbo].[MyTable] WHERE Id = 1 SELECT * FROM [dbo].[MyTable] WHERE Id = 2 SELECT * FROM [dbo].[MyTable] WHERE Id = 3 SQL Server memorizza tre piani di esecuzione nella plan cache. SELECT * FROM [dbo].[MyTable] WHERE Id = @Id –- @Id = 1 SELECT * FROM [dbo].[MyTable] WHERE Id = @Id -- @Id = 2 SELECT * FROM [dbo].[MyTable] WHERE Id = @Id -- @Id = 3 SQL Server riutilizza lo stesso piano di esecuzione. • – Ottimizza l’uso della plan cache se vengono usate molte query “Ad- Hoc”. November 28°, 2015 #sqlsatParma #sqlsat462 DEMO – Controllo sull’utilizzo della plan cache – Ad-Hoc Workloads November 28°, 2015 #sqlsatParma #sqlsat462 Conclusioni Se scegliamo un O/RM per interagire con il database, è necessario conoscerne pregi e difetti. L’O/RM è una scelta quasi obbligata per gestire la persistenza di un Domain Model. Jeremy D. Miller (http://jeremydmiller.com) November 28°, 2015 #sqlsatParma #sqlsat462 Resources Entity Framework Performance considerations http://msdn.microsoft.com/en-us/data/hh949853.aspx Entity Framework – ADO.NET Team Blog http://blogs.msdn.com/b/adonet Julie Lerman Blog http://thedatafarm.com/blog Entity Framework Tutorial http://www.entityframeworktutorial.net EntityFramework.Extended https://github.com/loresoft/EntityFramework.Extended November 28°, 2015 #sqlsatParma #sqlsat462 Q&A Questions? November 28°, 2015 #sqlsatParma #sqlsat462 #sqlsatParma #sqlsat462 http://speakerscore.com/SqlSatParma2015 http://speakerscore.com/SQLEF THANKS! November 28°, 2015 #sqlsatParma #sqlsat462