devfm #20 : sqldatabasecommand, un simple object mapping toolkit

27
1 Denis Voituron .Net Software Architect Simple Object Mapping SqlDatabaseCommand [email protected] www.dvoituron.be @denisvoituron

Upload: denis-voituron

Post on 16-Jan-2017

1.396 views

Category:

Software


0 download

TRANSCRIPT

Page 1: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

1

Denis Voituron.Net Software Architect

Simple Object Mapping SqlDatabaseCommand

[email protected] www.dvoituron.be @denisvoituron

Page 2: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

2

About meDenis Voituron

Civil engineer (Mons)Company founderDeveloper: VB3, VB.Net, C#.Net Software Architect (NRB)BloggerSpeaker (DevApps.be)

www.dvoituron.be

Page 3: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

3

Agenda• Background

• SQL Architecture• ADO.NET• EntityFramework• Comparaison

• Simple Object Mapping• Dapper.NET• SqlDatabaseCommand• SQLite

• SQL Server CLR Stored Procedures

Page 4: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

4

Background

Page 5: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

5

Architecture

SQL

SQLSQL

Page 6: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

6

SCOTT DatabaseEMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO7839 KING PRESIDENT 17-NOV-81 5000 10

7698 BLAKE MANAGER 7839 01-MAY-81 2850 30

7756 CLARK MANAGER 7839 09-JUN-81 1500 10

... ...

... ...

7456 JONES MANAGER 7839 02-APR-81 2975 20

DEPTNO DNAME LOC10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIOS BOSTON

Page 7: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

7

ADO.NETusing (var connection = new SqlConnection(CONNECTION_STRING)){ connection.Open();

connection.Close();}

SELECT ENAME FROM EMP WHERE EMPNO = 7369

using (var cmd = connection.CreateCommand()) { cmd.CommandText = "SELECT ENAME " + " FROM EMP " + " WHERE EMPNO = 7369 ";

}

using (var adapter = new SqlDataAdapter(cmd)) { DataTable table = new DataTable(); adapter.Fill(table); string name = table.Rows[0].Field<string>("ENAME"); }

Page 8: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

8

Entity Framework

var db = new SCOTTEntities();

var query = from e in db.EMPs where e.EMPNO == 7369 select e.ENAME;

var name = query.First();

var db = new SCOTTEntities();

var query = from e in db.EMPs where e.EMPNO == 7369 select e;

var name = query.First().DEPT.DNAME; SELECT TOP (1) [Extent1].[ENAME] AS [ENAME] FROM [dbo].[EMP] AS [Extent1] WHERE 7369 = [Extent1].[EMPNO]

SELECT TOP (1) [Extent1].[EMPNO] AS [EMPNO], [Extent1].[ENAME] AS [ENAME], [Extent1].[JOB] AS [JOB], [Extent1].[MGR] AS [MGR], [Extent1].[HIREDATE] AS [HIREDATE], [Extent1].[SAL] AS [SAL], [Extent1].[COMM] AS [COMM], [Extent1].[DEPTNO] AS [DEPTNO] FROM [dbo].[EMP] AS [Extent1] WHERE 7369 = [Extent1].[EMPNO]

SELECT [Extent1].[DEPTNO] AS [DEPTNO], [Extent1].[DNAME] AS [DNAME], [Extent1].[LOC] AS [LOC] FROM [dbo].[DEPT] AS [Extent1] WHERE [Extent1].[DEPTNO] = @V1

Object Relational Mapping

Page 9: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

9

ADO.NET vs Entity Framework

http://stackoverflow.com/questions/2698151/entity-framework-vs-linq-to-sql-vs-ado-net-with-stored-procedures

Performance

Speed of Development

Maintainable code (neat)

Flexibility

Scalability

ADO EF

Page 10: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

10

Performances

http://blogs.msdn.com/b/adonet/archive/2012/02/14/sneak-preview-entity-framework-5-0-performance-improvements.aspx

Page 11: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

11

Simple Object Mapping

Page 12: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

12

• Library that will extend IDbConnection

• Need an opened connection

Dapper.NET

https://github.com/StackExchange/dapper-dot-net

using (var connection = new SqlConnection(CONNECTION_STRING)){ connection.Open();

string sql = "SELECT * FROM EMP WHERE EMPNO = @Id"; var emp = connection.Query<EMP>(sql, new { Id = 7369 }); }

Page 13: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

13

• Query

• Query Dynamic

• ExecuteScalar

• Execute

• Buffered

Dapper.NETstring sql = "SELECT * FROM EMP WHERE EMPNO = @Id";var emp = connection.Query<EMP>(sql, new { Id = 7369 });

string sql = "SELECT * FROM EMP WHERE EMPNO = @Id";var emp = connection.Query(sql, new { Id = 7369 });

string sql = "SELECT ENAME FROM EMP WHERE EMPNO = @Id";var emp = connection.ExecuteScalar<string>(sql, new { Id = 7369 });

var n = connection.Execute(“DELETE FROM EMP");

var emp = connection.Query(sql, buffered: false);

Page 14: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

14

SqlDatabaseCommand• Object and Commands

• Construction and neat destruction• Optimizing SQL and Parameters (avoid SQL

injection)• Automatic conversion to C# objects• Generation of C# entities• Management of logs and traces

• Extension method of System.Data• Transform C# properties to SQL parameters• DBNull• ...https://github.com/Apps72/Dev.Data

Page 15: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

15

SqlDatabaseCommand• Sample

https://github.com/Apps72/Dev.Data

using (var cmd = new SqlDatabaseCommand(CONNECTION_STRING)){

}

cmd.CommandText.AppendLine(" SELECT * "); cmd.CommandText.AppendLine(" FROM EMP ");

var emps = cmd.ExecuteTable<Employee>();

cmd.CommandText.AppendLine(" WHERE HIREDATE = @HireDate "); cmd.Parameters.AddValues(new { HireDate = new DateTime(1980, 12, 17) });

Page 16: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

16

9876 NEW

• Main methodsSqlDatabaseCommandEMPNO ENAME

7839 KING

7698 BLAKE

7756 CLARK

...

...

7456 JONES

var emps = cmd.ExecuteTable<Employee>();

• ExecuteTable

var smith = cmd.ExecuteRow<Employee>();

• ExecuteRow

var name = cmd.ExecuteScalar<String>();

• ExecuteScalar

var n = cmd.ExecuteNonQuery();

• ExecuteQuery

Page 17: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

17

• ParametersSqlDatabaseCommand

cmd.CommandText.AppendLine(" SELECT ENAME ") .AppendLine(" FROM EMP ") .AppendLine(" WHERE EMPNO = @EmpNo ") .AppendLine(" AND HIREDATE = @HireDate ");

cmd.Parameters.AddWithValue("@EmpNo", 7369);cmd.Parameters.AddWithValue("@HireDate", new DateTime(1980, 12, 17));

var name = cmd.ExecuteScalar();

cmd.CommandText.AppendLine(" SELECT ENAME ") .AppendLine(" FROM EMP ") .AppendLine(" WHERE EMPNO = @EmpNo ") .AppendLine(" AND HIREDATE = @HireDate ");

cmd.Parameters.AddValues(new { EmpNo = 7369, HireDate = new DateTime(1980, 12, 17) });

var name = cmd.ExecuteScalar();

Page 18: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

18

• Traces• Logging

• Query Formatter

SqlDatabaseCommandcmd.Log = Console.WriteLine;

cmd.Log = (message) => { Console.WriteLine(message); };

string formatted = cmd.GetCommandTextFormatted(QueryFormat.Text);

SELECT ENAME FROM EMP WHERE EMPNO = 7369 AND HIREDATE = '1970-05-04 14:15:16'

string formatted = cmd.GetCommandTextFormatted(QueryFormat.Html);

SELECT ENAME FROM EMP WHERE EMPNO = 7369 AND HIREDATE = '1970-05-04 14:15:16'

Page 19: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

19

• Entities GeneratorSqlDatabaseCommand

T4

Entities.tt

// *********************************************// Code Generated with Apps72.Dev.Data.Generator// *********************************************using System;

namespace Data.Tests.Entities{ /// <summary /> public partial class BONUS { /// <summary /> public virtual String ENAME { get; set; } /// <summary /> public virtual String JOB { get; set; } /// <summary /> public virtual Int32? SAL { get; set; } /// <summary /> public virtual Int32? COMM { get; set; } } /// <summary /> public partial class DEPT { /// <summary /> public virtual Int32 DEPTNO { get; set; } /// <summary /> public virtual String DNAME { get; set; } /// <summary /> public virtual String LOC { get; set; } }

Save

var entitiesGenerator = new SqlEntitiesGenerator(CONNECTION_STRING);foreach (var table in entitiesGenerator.Tables){ ...}

Page 20: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

20

• Best PracticeSqlDatabaseCommandpublic class DataService : IDataService{ public SqlDatabaseCommand GetDatabaseCommand() { return new SqlDatabaseCommand(CONNECTION_STRING); }

public SqlDatabaseCommand GetDatabaseCommand(SqlTransaction trans) { return new SqlDatabaseCommand(trans.Connection, trans); }} using (var cmd =

service.GetDatabaseCommand()){ ...}

Page 21: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

21

• Microsoft.Data.Sqlite• SqliteDatabaseCommand

SQLitehttps://www.myget.org/F/aspnetcidev/api/v2

public SqliteDatabaseCommand GetDatabaseCommand(){ return new SqliteDatabaseCommand("Filename=Scott.db");}

public IEnumerable<Scott.EMP> GetAllEmployees(){ using (var cmd = this.GetDatabaseCommand()) { cmd.CommandText.AppendLine(" SELECT * FROM EMP "); return cmd.ExecuteTable<Scott.EMP>(); }}

Page 22: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

22

CLR Stored Procedures

Page 23: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

23

• What?• You can now write stored procedures, triggers, user-

defined types, user-defined functions, user-defined aggregates, and streaming table-valued functions, using any .NET Framework language

• Why?• Performances• Development tools (VS, GIT, …)• Centralisation du code• Déploiement

CLR Stored Procedures

https://msdn.microsoft.com/en-us/library/ms131102.aspx

Page 24: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

24

• Create a Class Library• CLR Nuget Package

SqlDatabaseCommand

Page 25: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

25

SqlDatabaseCommand[SqlFunction(DataAccess = DataAccessKind.Read)]public static int GetMaximumAge(){ using (var cmd = new SqlDatabaseCommand("context connection=true")) { ... }}

C#

CREATE FUNCTION GetMaximumAge()RETURNS INT AS EXTERNAL NAME SampleSqlDatabaseCommandClr.SampleCLR.GetMaximumAge

SQL

Page 26: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

26

SqlDatabaseCommand[SqlFunction()]public static bool IsComparableTo(string text1, string text2){ return text1.ComparableTo(text2) == 0;}

SELECT dbo.IsComparableTo('Maison', 'House') -- FALSESELECT dbo.IsComparableTo('St Ecole', 'Saint''école&') -- TRUESELECT dbo.IsComparableTo('A''&é', 'aE') -- TRUE

Page 27: DevFM #20 : SqlDatabaseCommand, un Simple Object Mapping Toolkit

27

Simple Object Mapping

ADO.NET EntityFramework

SQLite

Dapper.NETSqlDatabaseCommandCLR Stored Procedure

SQL Databases

Conclusion

Samples: https://github.com/dvoituron/SampleSqlDatabaseCommand