Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Dapper
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
Dapper
Commits
3be5fd77
Commit
3be5fd77
authored
May 16, 2011
by
mgravell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
c# 3.0 / .NET 3.5 support
parent
19af49f2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
217 additions
and
48 deletions
+217
-48
Dapper NET35.csproj
Dapper NET35/Dapper NET35.csproj
+59
-0
Dapper.sln
Dapper.sln
+12
-0
SqlMapper.cs
Dapper/SqlMapper.cs
+146
-48
No files found.
Dapper NET35/Dapper NET35.csproj
0 → 100644
View file @
3be5fd77
<?xml version="1.0" encoding="utf-8"?>
<Project
ToolsVersion=
"4.0"
DefaultTargets=
"Build"
xmlns=
"http://schemas.microsoft.com/developer/msbuild/2003"
>
<PropertyGroup>
<Configuration
Condition=
" '$(Configuration)' == '' "
>
Debug
</Configuration>
<Platform
Condition=
" '$(Platform)' == '' "
>
AnyCPU
</Platform>
<ProductVersion>
8.0.30703
</ProductVersion>
<SchemaVersion>
2.0
</SchemaVersion>
<ProjectGuid>
{B26305D8-3A89-4D68-A981-9BBF378B81FA}
</ProjectGuid>
<OutputType>
Library
</OutputType>
<AppDesignerFolder>
Properties
</AppDesignerFolder>
<RootNamespace>
Dapper_NET35
</RootNamespace>
<AssemblyName>
Dapper NET35
</AssemblyName>
<TargetFrameworkVersion>
v3.5
</TargetFrameworkVersion>
<FileAlignment>
512
</FileAlignment>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "
>
<DebugSymbols>
true
</DebugSymbols>
<DebugType>
full
</DebugType>
<Optimize>
false
</Optimize>
<OutputPath>
bin\Debug\
</OutputPath>
<DefineConstants>
TRACE;DEBUG;CSHARP30
</DefineConstants>
<ErrorReport>
prompt
</ErrorReport>
<WarningLevel>
4
</WarningLevel>
<LangVersion>
3
</LangVersion>
</PropertyGroup>
<PropertyGroup
Condition=
" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "
>
<DebugType>
pdbonly
</DebugType>
<Optimize>
true
</Optimize>
<OutputPath>
bin\Release\
</OutputPath>
<DefineConstants>
TRACE;CSHARP30
</DefineConstants>
<ErrorReport>
prompt
</ErrorReport>
<WarningLevel>
4
</WarningLevel>
<LangVersion>
3
</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Core"
/>
<Reference
Include=
"System.Data"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"..\Dapper\Properties\AssemblyInfo.cs"
>
<Link>
AssemblyInfo.cs
</Link>
</Compile>
<Compile
Include=
"..\Dapper\SqlMapper.cs"
>
<Link>
SqlMapper.cs
</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder
Include=
"Properties\"
/>
</ItemGroup>
<Import
Project=
"$(MSBuildToolsPath)\Microsoft.CSharp.targets"
/>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
\ No newline at end of file
Dapper.sln
View file @
3be5fd77
...
...
@@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper", "Dapper\Dapper.csp
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DapperTests", "Tests\DapperTests.csproj", "{A2A80512-11F4-4028-A995-505463632C84}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapper NET35", "Dapper NET35\Dapper NET35.csproj", "{B26305D8-3A89-4D68-A981-9BBF378B81FA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
...
...
@@ -35,6 +37,16 @@ Global
{A2A80512-11F4-4028-A995-505463632C84}.Release|Mixed Platforms.Build.0 = Release|x86
{A2A80512-11F4-4028-A995-505463632C84}.Release|x86.ActiveCfg = Release|x86
{A2A80512-11F4-4028-A995-505463632C84}.Release|x86.Build.0 = Release|x86
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Any CPU.Build.0 = Release|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B26305D8-3A89-4D68-A981-9BBF378B81FA}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
...
...
Dapper/SqlMapper.cs
View file @
3be5fd77
/*
License: http://www.apache.org/licenses/LICENSE-2.0
Home page: http://code.google.com/p/dapper-dot-net/
*/
Note: to build on C# 3.0 + .NET 3.5, include the CSHARP30 compiler symbol (and yes,
I know the difference between language and runtime versions; this is a compromise).
*/
using
System
;
using
System.Collections
;
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
System.ComponentModel
;
using
System.Data
;
using
System.Dynamic
;
using
System.Linq
;
using
System.Reflection
;
using
System.Reflection.Emit
;
using
System.
ComponentModel
;
using
System.
Text
;
namespace
Dapper
{
...
...
@@ -29,8 +30,44 @@ class CacheInfo
public
object
[]
OtherDeserializers
{
get
;
set
;
}
public
Action
<
IDbCommand
,
object
>
ParamReader
{
get
;
set
;
}
}
static
readonly
ConcurrentDictionary
<
Identity
,
CacheInfo
>
queryCache
=
new
ConcurrentDictionary
<
Identity
,
CacheInfo
>();
#if CSHARP30
private
static
readonly
System
.
Threading
.
ReaderWriterLockSlim
queryLock
=
new
System
.
Threading
.
ReaderWriterLockSlim
();
private
static
readonly
Dictionary
<
Identity
,
CacheInfo
>
_queryCache
=
new
Dictionary
<
Identity
,
CacheInfo
>();
private
static
void
SetQueryCache
(
Identity
key
,
CacheInfo
value
)
{
queryLock
.
EnterWriteLock
();
try
{
_queryCache
[
key
]
=
value
;
}
finally
{
queryLock
.
ExitWriteLock
();
}
}
private
static
bool
TryGetQueryCache
(
Identity
key
,
out
CacheInfo
value
)
{
queryLock
.
EnterReadLock
();
try
{
return
_queryCache
.
TryGetValue
(
key
,
out
value
);
}
finally
{
queryLock
.
ExitReadLock
();
}
}
#else
static
readonly
System
.
Collections
.
Concurrent
.
ConcurrentDictionary
<
Identity
,
CacheInfo
>
_queryCache
=
new
System
.
Collections
.
Concurrent
.
ConcurrentDictionary
<
Identity
,
CacheInfo
>();
private
static
void
SetQueryCache
(
Identity
key
,
CacheInfo
value
)
{
_queryCache
[
key
]
=
value
;
}
private
static
bool
TryGetQueryCache
(
Identity
key
,
out
CacheInfo
value
)
{
return
_queryCache
.
TryGetValue
(
key
,
out
value
);
}
#endif
static
readonly
Dictionary
<
RuntimeTypeHandle
,
DbType
>
typeMap
;
static
SqlMapper
()
...
...
@@ -91,7 +128,7 @@ private static DbType LookupDbType(Type type)
private
class
Identity
:
IEquatable
<
Identity
>
{
internal
Identity
(
string
sql
,
IDbConnection
cnn
,
Type
type
,
Type
parametersType
,
Type
[]
otherTypes
=
null
)
internal
Identity
(
string
sql
,
IDbConnection
cnn
,
Type
type
,
Type
parametersType
,
Type
[]
otherTypes
)
{
this
.
sql
=
sql
;
this
.
connectionString
=
cnn
.
ConnectionString
;
...
...
@@ -141,13 +178,19 @@ public bool Equals(Identity other)
/// Execute parameterized SQL
/// </summary>
/// <returns>Number of rows affected</returns>
public
static
int
Execute
(
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
int
Execute
(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
object
param
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
null
,
param
==
null
?
null
:
param
.
GetType
());
var
identity
=
new
Identity
(
sql
,
cnn
,
null
,
param
==
null
?
null
:
param
.
GetType
()
,
null
);
var
info
=
GetCacheInfo
(
param
,
identity
);
return
ExecuteCommand
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
,
commandTimeout
,
commandType
);
}
#if !CSHARP30
/// <summary>
/// Return a list of dynamic objects, reader is closed after the call
/// </summary>
...
...
@@ -155,10 +198,16 @@ public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, dyn
{
return
Query
<
FastExpando
>(
cnn
,
sql
,
param
as
object
,
transaction
,
buffered
,
commandTimeout
,
commandType
);
}
#endif
// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new <space> get new object
public
static
IEnumerable
<
T
>
Query
<
T
>(
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
IEnumerable
<
T
>
Query
<
T
>(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
object
param
,
IDbTransaction
transaction
,
bool
buffered
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
var
data
=
QueryInternal
<
T
>(
cnn
,
sql
,
param
as
object
,
transaction
,
commandTimeout
,
commandType
);
return
buffered
?
data
.
ToList
()
:
data
;
...
...
@@ -167,9 +216,16 @@ public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, dynami
/// <summary>
/// Execute a command that returns multiple result sets, and access each in turn
/// </summary>
public
static
GridReader
QueryMultiple
(
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
GridReader
QueryMultiple
(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
object
param
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
GridReader
),
param
==
null
?
null
:
param
.
GetType
());
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
GridReader
),
param
==
null
?
null
:
param
.
GetType
()
,
null
);
var
info
=
GetCacheInfo
(
param
,
identity
);
IDbCommand
cmd
=
null
;
...
...
@@ -191,9 +247,9 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, dynam
/// <summary>
/// Return a typed list of objects, reader is closed after the call
/// </summary>
private
static
IEnumerable
<
T
>
QueryInternal
<
T
>(
this
IDbConnection
cnn
,
string
sql
,
object
param
=
null
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
private
static
IEnumerable
<
T
>
QueryInternal
<
T
>(
this
IDbConnection
cnn
,
string
sql
,
object
param
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
CommandType
?
commandType
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
T
),
param
==
null
?
null
:
param
.
GetType
());
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
T
),
param
==
null
?
null
:
param
.
GetType
()
,
null
);
var
info
=
GetCacheInfo
(
param
,
identity
);
using
(
var
cmd
=
SetupCommand
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
,
commandTimeout
,
commandType
))
...
...
@@ -202,8 +258,8 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
{
if
(
info
.
Deserializer
==
null
)
{
info
.
Deserializer
=
GetDeserializer
<
T
>(
reader
);
queryCache
[
identity
]
=
info
;
info
.
Deserializer
=
GetDeserializer
<
T
>(
reader
,
0
,
-
1
,
false
);
SetQueryCache
(
identity
,
info
)
;
}
var
deserializer
=
(
Func
<
IDataReader
,
T
>)
info
.
Deserializer
;
...
...
@@ -230,36 +286,55 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
/// <param name="splitOn">The Field we should split and read the second object from (default: id)</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout</param>
/// <returns></returns>
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TReturn
>(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TReturn
>
map
,
object
param
,
IDbTransaction
transaction
,
bool
buffered
,
string
splitOn
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
return
MultiMap
<
TFirst
,
TSecond
,
DontMap
,
DontMap
,
DontMap
,
TReturn
>(
cnn
,
sql
,
map
,
param
as
object
,
transaction
,
buffered
,
splitOn
,
commandTimeout
,
commandType
);
}
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TThird
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TThird
,
TReturn
>(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TReturn
>
map
,
object
param
,
IDbTransaction
transaction
,
bool
buffered
,
string
splitOn
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
return
MultiMap
<
TFirst
,
TSecond
,
TThird
,
DontMap
,
DontMap
,
TReturn
>(
cnn
,
sql
,
map
,
param
as
object
,
transaction
,
buffered
,
splitOn
,
commandTimeout
,
commandType
);
}
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TReturn
>(
#if CSHARP30
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TReturn
>
map
,
object
param
,
IDbTransaction
transaction
,
bool
buffered
,
string
splitOn
,
int
?
commandTimeout
,
CommandType
?
commandType
#else
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
#endif
)
{
return
MultiMap
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
DontMap
,
TReturn
>(
cnn
,
sql
,
map
,
param
as
object
,
transaction
,
buffered
,
splitOn
,
commandTimeout
,
commandType
);
}
#if !CSHARP30
public
static
IEnumerable
<
TReturn
>
Query
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
Func
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>
map
,
dynamic
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
{
return
MultiMap
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
cnn
,
sql
,
map
,
param
as
object
,
transaction
,
buffered
,
splitOn
,
commandTimeout
,
commandType
);
}
#endif
class
DontMap
{}
static
IEnumerable
<
TReturn
>
MultiMap
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
object
map
,
object
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
static
IEnumerable
<
TReturn
>
MultiMap
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
object
map
,
object
param
,
IDbTransaction
transaction
,
bool
buffered
,
string
splitOn
,
int
?
commandTimeout
,
CommandType
?
commandType
)
{
var
results
=
MultiMapImpl
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
cnn
,
sql
,
map
,
param
,
transaction
,
splitOn
,
commandTimeout
,
commandType
);
return
buffered
?
results
.
ToList
()
:
results
;
}
static
IEnumerable
<
TReturn
>
MultiMapImpl
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
object
map
,
object
param
=
null
,
IDbTransaction
transaction
=
null
,
string
splitOn
=
"Id"
,
int
?
commandTimeout
=
null
,
CommandType
?
commandType
=
null
)
static
IEnumerable
<
TReturn
>
MultiMapImpl
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>(
this
IDbConnection
cnn
,
string
sql
,
object
map
,
object
param
,
IDbTransaction
transaction
,
string
splitOn
,
int
?
commandTimeout
,
CommandType
?
commandType
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
TFirst
),
param
==
null
?
null
:
param
.
GetType
(),
otherTypes
:
new
[]
{
typeof
(
TFirst
),
typeof
(
TSecond
),
typeof
(
TThird
),
typeof
(
TFourth
),
typeof
(
TFifth
)
});
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
TFirst
),
param
==
null
?
null
:
param
.
GetType
(),
new
[]
{
typeof
(
TFirst
),
typeof
(
TSecond
),
typeof
(
TThird
),
typeof
(
TFourth
),
typeof
(
TFifth
)
});
var
info
=
GetCacheInfo
(
param
,
identity
);
using
(
var
cmd
=
SetupCommand
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
,
commandTimeout
,
commandType
))
...
...
@@ -288,35 +363,35 @@ class DontMap {}
var
otherDeserializer
=
new
List
<
object
>();
int
split
=
nextSplit
();
info
.
Deserializer
=
GetDeserializer
<
TFirst
>(
reader
,
0
,
split
);
info
.
Deserializer
=
GetDeserializer
<
TFirst
>(
reader
,
0
,
split
,
false
);
if
(
typeof
(
TSecond
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TSecond
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TSecond
>(
reader
,
split
,
next
-
split
,
true
));
split
=
next
;
}
if
(
typeof
(
TThird
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TThird
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TThird
>(
reader
,
split
,
next
-
split
,
true
));
split
=
next
;
}
if
(
typeof
(
TFourth
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TFourth
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TFourth
>(
reader
,
split
,
next
-
split
,
true
));
split
=
next
;
}
if
(
typeof
(
TFifth
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TFifth
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TFifth
>(
reader
,
split
,
next
-
split
,
true
));
}
info
.
OtherDeserializers
=
otherDeserializer
.
ToArray
();
queryCache
[
identity
]
=
info
;
SetQueryCache
(
identity
,
info
)
;
}
var
deserializer
=
(
Func
<
IDataReader
,
TFirst
>)
info
.
Deserializer
;
...
...
@@ -348,8 +423,12 @@ class DontMap {}
if
(
info
.
OtherDeserializers
.
Length
>
3
)
{
#if CSHARP30
throw
new
NotSupportedException
();
#else
var
deserializer5
=
(
Func
<
IDataReader
,
TFifth
>)
info
.
OtherDeserializers
[
3
];
mapIt
=
r
=>
((
Func
<
TFirst
,
TSecond
,
TThird
,
TFourth
,
TFifth
,
TReturn
>)
map
)(
deserializer
(
r
),
deserializer2
(
r
),
deserializer3
(
r
),
deserializer4
(
r
),
deserializer5
(
r
));
#endif
}
}
}
...
...
@@ -366,7 +445,7 @@ class DontMap {}
private
static
CacheInfo
GetCacheInfo
(
object
param
,
Identity
identity
)
{
CacheInfo
info
;
if
(!
queryCache
.
TryGetValu
e
(
identity
,
out
info
))
if
(!
TryGetQueryCach
e
(
identity
,
out
info
))
{
info
=
new
CacheInfo
();
if
(
param
!=
null
)
...
...
@@ -384,13 +463,16 @@ private static CacheInfo GetCacheInfo(object param, Identity identity)
return
info
;
}
private
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
private
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
,
int
length
,
bool
returnNullIfFirstMissing
)
{
#if !CSHARP30
// dynamic is passed in as Object ... by c# design
if
(
typeof
(
T
)
==
typeof
(
object
)
||
typeof
(
T
)
==
typeof
(
FastExpando
))
if
(
typeof
(
T
)
==
typeof
(
object
)
||
typeof
(
T
)
==
typeof
(
FastExpando
))
{
return
GetDynamicDeserializer
<
T
>(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
);
}
#endif
if
(
typeof
(
T
).
IsClass
&&
typeof
(
T
)
!=
typeof
(
string
))
{
return
GetClassDeserializer
<
T
>(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
);
...
...
@@ -398,8 +480,8 @@ private static CacheInfo GetCacheInfo(object param, Identity identity)
return
GetStructDeserializer
<
T
>();
}
private
class
FastExpando
:
DynamicObject
#if !CSHARP30
private
class
FastExpando
:
System
.
Dynamic
.
DynamicObject
{
IDictionary
<
string
,
object
>
data
;
...
...
@@ -408,19 +490,20 @@ public static FastExpando Attach(IDictionary<string, object> data)
return
new
FastExpando
{
data
=
data
};
}
public
override
bool
TrySetMember
(
SetMemberBinder
binder
,
object
value
)
public
override
bool
TrySetMember
(
S
ystem
.
Dynamic
.
S
etMemberBinder
binder
,
object
value
)
{
data
[
binder
.
Name
]
=
value
;
return
true
;
}
public
override
bool
TryGetMember
(
GetMemberBinder
binder
,
out
object
result
)
public
override
bool
TryGetMember
(
System
.
Dynamic
.
GetMemberBinder
binder
,
out
object
result
)
{
return
data
.
TryGetValue
(
binder
.
Name
,
out
result
);
}
}
private
static
Func
<
IDataReader
,
T
>
GetDynamicDeserializer
<
T
>(
IDataRecord
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
private
static
Func
<
IDataReader
,
T
>
GetDynamicDeserializer
<
T
>(
IDataRecord
reader
,
int
startBound
,
int
length
,
bool
returnNullIfFirstMissing
)
{
if
(
length
==
-
1
)
{
...
...
@@ -444,8 +527,8 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
//we know this is an object so it will not box
return
(
T
)(
object
)
FastExpando
.
Attach
(
row
);
};
}
#endif
[
Browsable
(
false
),
EditorBrowsable
(
EditorBrowsableState
.
Never
)]
[
Obsolete
(
"This method is for internal usage only"
,
true
)]
public
static
void
PackListParameters
(
IDbCommand
command
,
string
namePrefix
,
object
value
)
...
...
@@ -482,10 +565,13 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
}
else
{
command
.
CommandText
=
command
.
CommandText
.
Replace
(
namePrefix
,
"("
+
string
.
Join
(
","
,
Enumerable
.
Range
(
1
,
count
).
Select
(
i
=>
namePrefix
+
i
.
ToString
())
)
+
")"
);
var
sb
=
new
StringBuilder
(
"("
).
Append
(
namePrefix
).
Append
(
1
);
for
(
int
i
=
2
;
i
<=
count
;
i
++)
{
sb
.
Append
(
','
).
Append
(
namePrefix
).
Append
(
i
);
}
string
inQuery
=
sb
.
Append
(
')'
).
ToString
();
command
.
CommandText
=
command
.
CommandText
.
Replace
(
namePrefix
,
inQuery
);
}
}
...
...
@@ -659,7 +745,13 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction tranaction,
};
}
public
static
Func
<
IDataReader
,
T
>
GetClassDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
public
static
Func
<
IDataReader
,
T
>
GetClassDeserializer
<
T
>(
#if CSHARP30
IDataReader
reader
,
int
startBound
,
int
length
,
bool
returnNullIfFirstMissing
#else
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
#endif
)
{
var
dm
=
new
DynamicMethod
(
string
.
Format
(
"Deserialize{0}"
,
Guid
.
NewGuid
()),
typeof
(
T
),
new
[]
{
typeof
(
IDataReader
)
},
true
);
...
...
@@ -833,7 +925,7 @@ public IEnumerable<T> Read<T>()
{
if
(
reader
==
null
)
throw
new
ObjectDisposedException
(
GetType
().
Name
);
if
(
consumed
)
throw
new
InvalidOperationException
(
"Each grid can only be iterated once"
);
var
deserializer
=
GetDeserializer
<
T
>(
reader
);
var
deserializer
=
GetDeserializer
<
T
>(
reader
,
0
,
-
1
,
false
);
consumed
=
true
;
return
ReadDeferred
(
gridIndex
,
deserializer
);
}
...
...
@@ -902,7 +994,13 @@ class ParamInfo
}
public
void
Add
(
string
name
,
object
value
=
null
,
DbType
?
dbType
=
null
,
ParameterDirection
?
direction
=
null
,
int
?
size
=
null
)
public
void
Add
(
#if CSHARP30
string
name
,
object
value
,
DbType
?
dbType
,
ParameterDirection
?
direction
,
int
?
size
#else
string
name
,
object
value
=
null
,
DbType
?
dbType
=
null
,
ParameterDirection
?
direction
=
null
,
int
?
size
=
null
#endif
)
{
parameters
[
name
]
=
new
ParamInfo
()
{
Name
=
name
,
Value
=
value
,
ParameterDirection
=
direction
??
ParameterDirection
.
Input
,
DbType
=
dbType
,
Size
=
size
};
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment