Skip to content

Commit 4df70fb

Browse files
author
dmitry@jet.com
committed
some changes in wording
1 parent 339c454 commit 4df70fb

File tree

1 file changed

+48
-48
lines changed

1 file changed

+48
-48
lines changed

docs/content/comparison.fsx

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,28 @@
33
A comparison on SQL Server data access methods
44
==============================================
55
6-
Type providers + Query Expressions
6+
Type providers + Query Expressions
77
-----------------------------------------
88
9-
F# Query Expressions (aka LINQ 2.0) is lovely and useful technology. It makes writing data access code a pleasant exercise.
10-
There are several different implementations available: [SQLProvider][sql] (recent community effort), [SqlDataConnection][linq2sql]/[DbmlFile][dbml]
11-
and [SqlEntityConnection][ef]/[EdmxFile][edmx].
12-
13-
But I would like to point out some reasons you might prefer SqlCommandProvider over those.
14-
Take a look at this [StackOverflow issue][soissue]. There are dozens of similar questions (hundreds if you include C# LINQ which is essentially
15-
the same issue).
16-
9+
F# Query Expressions (aka LINQ 2.0) is lovely and useful technology. It makes writing data access code a pleasant exercise.
10+
There are several different implementations available: [SQLProvider][sql] (recent community effort), [SqlDataConnection][linq2sql]/[DbmlFile][dbml]
11+
and [SqlEntityConnection][ef]/[EdmxFile][edmx].
12+
13+
But I would like to point out some reasons you might prefer SqlCommandProvider over those.
14+
Take a look at this [StackOverflow issue][soissue]. There are dozens of similar questions (hundreds if you include C# LINQ which is essentially
15+
the same issue).
16+
1717
So, what's a deal? The thing is, you can have perfectly valid F# code that compiles but still fails at run-time because of
18-
unsupported F#-to-SQL translation semantics. Contrary, SqlCommandProvider offers "What You See Is What You Get" approach.
19-
Once F# code involving SqlCommandProvider passes compilation stage you are guaranteed to have valid executable (both F# code and T-SQL).
20-
21-
Lack of control and opaqueness of F#-to-SQL conversion spells performance problems too.
22-
At times developers are really frustrated by ineffective T-SQL code generated by type providers (most of EF users are aware of this issue).
23-
Evolution and changes in T-SQL code generated by type provider may present certain problems too.
24-
A data access code that is performing well today can become suboptimal tomorrow.
25-
SqlCommandProvider gives you direct access to full power of T-SQL scripting including the latest features which are often
26-
unavailable in type providers because they target older or different versions of the system.
27-
18+
unsupported F#-to-SQL translation semantics. Contrary, SqlCommandProvider offers "What You See Is What You Get" approach.
19+
Once F# code involving SqlCommandProvider passes compilation stage you are guaranteed to have valid executable (both F# code and T-SQL).
20+
21+
Lack of control and opaqueness of F#-to-SQL conversion spells performance problems too.
22+
At times developers are really frustrated by ineffective T-SQL code generated by type providers (most of EF users are aware of this issue).
23+
Evolution and changes in T-SQL code generated by type provider may present certain problems too.
24+
A data access code that is performing well today can become suboptimal tomorrow.
25+
SqlCommandProvider gives you direct access to full power of T-SQL scripting including the latest features which are often
26+
unavailable in type providers because they target older or different versions of the system.
27+
2828
[sql]: http://github.com/fsprojects/SQLProvider
2929
[linq2sql]: http://msdn.microsoft.com/en-us/library/hh361033.aspx
3030
[dbml]: http://msdn.microsoft.com/en-us/library/hh361039.aspx
@@ -34,41 +34,40 @@ Type providers + Query Expressions
3434
3535
### Common for all TypeProviders
3636
37-
- You write just logic code, not POCO-objects and mappings
38-
- If your database changes, your code breaks on compile time
37+
- You write logic, not POCO-objects and mappings
38+
- If your database changes, your code breaks at compile time
3939
- No SQL-injection vulnerabilities
4040
- Commit to existing transactions so you can mix with other technologies
41-
- You can call stored procedures if needed.
42-
- Supports joins and nested in-queries so you can avoid "n+1 database hits" problems
41+
- You can call stored procedures if needed
42+
- Joins and nested in-queries are supported so you can avoid "n+1 database hits" problems
4343
4444
### FSharp.Data.SqlClient
4545
4646
Good:
4747
48-
- User has control of SQL-clauses
49-
- So you can hit database indexes with complex queries
50-
- SQL-syntax is already familiar for many
48+
- User has full control of SQL
49+
- Which allows full utilization of database indexes with complex queries
50+
- SQL syntax is already familiar for many
51+
- Exposes database objects directly in code
5152
- Supports async database operations
52-
- Use it e.g. for data processing backends
53+
- Used in production for enterprise development for years
5354
- Open source
5455
5556
Not so good:
5657
57-
- By default supports only Microsoft SQLServer and its SQL.
58+
- By default supports only Microsoft SQLServer and T-SQL
5859
- Code overhead if you have a large amount of different small operations
5960
- Doesn't generate domain model for work with C#
6061
61-
6262
### SQLProvider
6363
6464
Good:
6565
6666
- Supports any database (MSSQL, MySQL, Postgre, Oracle, Odbc, ...)
6767
- Changing the database is not actually huge work
68-
- Makes effective simple SQL
68+
- Makes effective simple SQL
6969
- Supports async database operations
70-
- Use it e.g. for web servers
71-
- User's code stays simple
70+
- Simplifies user code
7271
- Open source
7372
7473
Not so good:
@@ -77,6 +76,7 @@ Not so good:
7776
- FSharp/LINQ query-syntax is a learning curve
7877
- Doesn't generate domain model for work with C#
7978
- Most LINQ-operations supported, but not yet complex group-by scenarios
79+
- Updates in complex scenarios can be a pain
8080
8181
### SqlDataConnection
8282
@@ -87,7 +87,7 @@ Good:
8787
8888
Not so good:
8989
90-
- Generates EF-models on background
90+
- Generates EF-models in background
9191
- Not dynamic
9292
- Doesn't scale to large databases
9393
- FSharp/LINQ query-syntax is a learning curve
@@ -97,26 +97,26 @@ Not so good:
9797
[Dapper](https://code.google.com/p/dapper-dot-net/)
9898
-----------------------------------------
9999
100-
FSharp.Data.SqlClient is much closer to the family of micro-ORMs rather than complete solutions like EntityFramework and NHibernate,
100+
FSharp.Data.SqlClient is much closer to the family of micro-ORMs rather than complete solutions like EntityFramework and NHibernate,
101101
hence comparison with the best of the breed - Dapper.
102102
103-
Dapper is a micro-ORM by StackOverflow with a main goal of being extremely fast. Here is a [description](http://stackoverflow.com/tags/dapper/info)
103+
Dapper is a micro-ORM by StackOverflow with a main goal of being extremely fast. Here is a [description](http://stackoverflow.com/tags/dapper/info)
104104
from StackOverflow itself:
105105
106-
>dapper is a micro-ORM, offering core parameterization and materialization services, but (by design) not the full breadth of services that you might
107-
expect in a full ORM such as LINQ-to-SQL or Entity Framework. Instead, it focuses on making the materialization as fast as possible, with no overheads
106+
>dapper is a micro-ORM, offering core parameterization and materialization services, but (by design) not the full breadth of services that you might
107+
expect in a full ORM such as LINQ-to-SQL or Entity Framework. Instead, it focuses on making the materialization as fast as possible, with no overheads
108108
from things like identity managers - just "run this query and give me the (typed) data".
109109
110-
Let's start with performance to get it out of the way.
110+
Let's start with performance to get it out of the way.
111111
112-
Dapper comes with an excellent [benchmark](https://code.google.com/p/dapper-dot-net/source/browse/Tests/PerformanceTests.cs).
112+
Dapper comes with an excellent [benchmark](https://code.google.com/p/dapper-dot-net/source/browse/Tests/PerformanceTests.cs).
113113
The focus of the test is on deserialization. Here is how FSHarp.Data.SqlClient compares with all major .Net ORMs:
114114
115115
<img src="img/dapper.png"/>
116116
117-
Tests were executed against SqlExpress 2012 so the numbers are a bit higher than what you can see on
117+
Tests were executed against SqlExpress 2012 so the numbers are a bit higher than what you can see on
118118
[Dapper page](https://github.com/SamSaffron/dapper-dot-net#performance-of-select-mapping-over-500-iterations---poco-serialization).
119-
A test retrieves single record with 13 properties by random id 500 times and deserializes it. Runs for different ORMs are mixed up randomly.
119+
A test retrieves single record with 13 properties by random id 500 times and deserializes it. Runs for different ORMs are mixed up randomly.
120120
All executions are synchronous.
121121
122122
Note that we didn't put any specific effort into improving FSharp.Data.SqlClient performance for this test. The very nature of type providers helps to produce
@@ -127,32 +127,32 @@ Keeping in mind that FSharp.Data.SqlClient is not strictly an ORM in commonly un
127127
128128
* Because result types are auto-generated, FSharp.Data.SqlClient doesn't support so-called [multi-mapping](http://stackoverflow.com/a/6001902/862313)
129129
* As FSharp.Data.SqlClient is based on features specific for Sql Server 2012; Dapper provides better range of supported scenarios, including Mono
130-
* Other side of this is that FSharp.Data.SqlClient fully supports SqlServer-specific types like [hierarchyId](http://technet.microsoft.com/en-us/library/bb677173.aspx) and
130+
* Other side of this is that FSharp.Data.SqlClient fully supports SqlServer-specific types like [hierarchyId](http://technet.microsoft.com/en-us/library/bb677173.aspx) and
131131
[spatial types](http://blogs.msdn.com/b/adonet/archive/2013/12/09/microsoft-sqlserver-types-nuget-package-spatial-on-azure.aspx), which Dapper does not
132-
* FSharp.Data.SqlClient fully supports User-Defined Table Types for input parameters with no additional coding required,
132+
* FSharp.Data.SqlClient fully supports User-Defined Table Types for input parameters with no additional coding required,
133133
[as opposed to Dapper](http://stackoverflow.com/questions/6232978/does-dapper-support-sql-2008-table-valued-parameters)
134-
* Dapper intentionally has no support for `SqlConnection` management; FSharp.Data.SqlClient encapsulates `SqlConnection`
134+
* Dapper intentionally has no support for `SqlConnection` management; FSharp.Data.SqlClient encapsulates `SqlConnection`
135135
life-cycle including asynchronous scenarios while optionally accepting external `SqlTransaction`.
136136
137137
Following FSharp.Data.SqlClient features are unique:
138138
139139
* Reasonable auto-generated result type definition so there is no need to define it in code
140140
* This type also comes with `IDictionary<string,obj>` and `DynamicObject` implementation
141-
* Sql command is just a string for other ORMs, while FSHarp.Data.SqlClient verifies it and figures out input parameters and output types
141+
* Sql command is just a string for other ORMs, while FSHarp.Data.SqlClient verifies it and figures out input parameters and output types
142142
so design-time experience is simply unparalleled
143-
* Design-time verification means less run-time tests, less yak shaving synchronizing database schema with code definitions, and earliest possible
143+
* Design-time verification means less run-time tests, less yak shaving synchronizing database schema with code definitions, and earliest possible
144144
identification of bugs and mismatches
145145
* `SqlProgrammabilityProvider` lets user to explore stored procedures and user-defined functions right from the code with IntelliSense
146146
147147
148-
It is my believe that FSharp.Data.SqlClient comes closest to the mission of micro-ORM - to make conversion between data stored in database and .Net run-time types as painless as possible
148+
It is my believe that FSharp.Data.SqlClient comes closest to the mission of micro-ORM - to make conversion between data stored in database and .Net run-time types as painless as possible
149149
while keeping away from [object-relational impedance mismatch](http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch)
150150
as described in famous blog [The Vietnam of Computer Science](http://blogs.tedneward.com/2006/06/26/The+Vietnam+Of+Computer+Science.aspx) by Ted Neward.
151151
152152
[Generating strongly typed DataSets](http://msdn.microsoft.com/en-us/library/wha85tzb.aspx)
153153
-----------------------------------------
154154
155-
Using strongly typed DataSets requires creation of XSD schema which then used to generate C# code. Dubious pleasure of hand-crafting XSD aside,
155+
Using strongly typed DataSets requires creation of XSD schema which then used to generate C# code. Dubious pleasure of hand-crafting XSD aside,
156156
this traditional technique suffers from the same limitation as Entity Framework and such when compared to FSharp.Data.SqlClient:
157157
no design-time interaction with model database - it is up to a user to keep definitions and database schema in sync.
158158

0 commit comments

Comments
 (0)