Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Dapper
提交
0add8271
D
Dapper
项目概览
int
/
Dapper
大约 1 年 前同步成功
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Dapper
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0add8271
编写于
5月 11, 2011
作者:
S
Sam Saffron
浏览文件
操作
浏览文件
下载
差异文件
Merge with simon
上级
8edacbbc
7b316c2a
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
64 addition
and
93 deletion
+64
-93
Dapper/SqlMapper.cs
Dapper/SqlMapper.cs
+64
-93
未找到文件。
Dapper/SqlMapper.cs
浏览文件 @
0add8271
...
...
@@ -8,6 +8,7 @@
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
System.Data
;
using
System.Diagnostics
;
using
System.Dynamic
;
using
System.Linq
;
using
System.Reflection
;
...
...
@@ -31,51 +32,51 @@ class CacheInfo
}
static
readonly
ConcurrentDictionary
<
Identity
,
CacheInfo
>
queryCache
=
new
ConcurrentDictionary
<
Identity
,
CacheInfo
>();
static
readonly
Dictionary
<
Typ
e
,
DbType
>
typeMap
;
static
readonly
Dictionary
<
RuntimeTypeHandl
e
,
DbType
>
typeMap
;
static
SqlMapper
()
{
typeMap
=
new
Dictionary
<
Typ
e
,
DbType
>();
typeMap
[
typeof
(
byte
)]
=
DbType
.
Byte
;
typeMap
[
typeof
(
sbyte
)]
=
DbType
.
SByte
;
typeMap
[
typeof
(
short
)]
=
DbType
.
Int16
;
typeMap
[
typeof
(
ushort
)]
=
DbType
.
UInt16
;
typeMap
[
typeof
(
int
)]
=
DbType
.
Int32
;
typeMap
[
typeof
(
uint
)]
=
DbType
.
UInt32
;
typeMap
[
typeof
(
long
)]
=
DbType
.
Int64
;
typeMap
[
typeof
(
ulong
)]
=
DbType
.
UInt64
;
typeMap
[
typeof
(
float
)]
=
DbType
.
Single
;
typeMap
[
typeof
(
double
)]
=
DbType
.
Double
;
typeMap
[
typeof
(
decimal
)]
=
DbType
.
Decimal
;
typeMap
[
typeof
(
bool
)]
=
DbType
.
Boolean
;
typeMap
[
typeof
(
string
)]
=
DbType
.
String
;
typeMap
[
typeof
(
char
)]
=
DbType
.
StringFixedLength
;
typeMap
[
typeof
(
Guid
)]
=
DbType
.
Guid
;
typeMap
[
typeof
(
DateTime
)]
=
DbType
.
DateTime
;
typeMap
[
typeof
(
DateTimeOffset
)]
=
DbType
.
DateTimeOffset
;
typeMap
[
typeof
(
byte
[])]
=
DbType
.
Binary
;
typeMap
[
typeof
(
byte
?)]
=
DbType
.
Byte
;
typeMap
[
typeof
(
sbyte
?)]
=
DbType
.
SByte
;
typeMap
[
typeof
(
short
?)]
=
DbType
.
Int16
;
typeMap
[
typeof
(
ushort
?)]
=
DbType
.
UInt16
;
typeMap
[
typeof
(
int
?)]
=
DbType
.
Int32
;
typeMap
[
typeof
(
uint
?)]
=
DbType
.
UInt32
;
typeMap
[
typeof
(
long
?)]
=
DbType
.
Int64
;
typeMap
[
typeof
(
ulong
?)]
=
DbType
.
UInt64
;
typeMap
[
typeof
(
float
?)]
=
DbType
.
Single
;
typeMap
[
typeof
(
double
?)]
=
DbType
.
Double
;
typeMap
[
typeof
(
decimal
?)]
=
DbType
.
Decimal
;
typeMap
[
typeof
(
bool
?)]
=
DbType
.
Boolean
;
typeMap
[
typeof
(
char
?)]
=
DbType
.
StringFixedLength
;
typeMap
[
typeof
(
Guid
?)]
=
DbType
.
Guid
;
typeMap
[
typeof
(
DateTime
?)]
=
DbType
.
DateTime
;
typeMap
[
typeof
(
DateTimeOffset
?)]
=
DbType
.
DateTimeOffset
;
typeMap
=
new
Dictionary
<
RuntimeTypeHandl
e
,
DbType
>();
typeMap
[
typeof
(
byte
)
.
TypeHandle
]
=
DbType
.
Byte
;
typeMap
[
typeof
(
sbyte
)
.
TypeHandle
]
=
DbType
.
SByte
;
typeMap
[
typeof
(
short
)
.
TypeHandle
]
=
DbType
.
Int16
;
typeMap
[
typeof
(
ushort
)
.
TypeHandle
]
=
DbType
.
UInt16
;
typeMap
[
typeof
(
int
)
.
TypeHandle
]
=
DbType
.
Int32
;
typeMap
[
typeof
(
uint
)
.
TypeHandle
]
=
DbType
.
UInt32
;
typeMap
[
typeof
(
long
)
.
TypeHandle
]
=
DbType
.
Int64
;
typeMap
[
typeof
(
ulong
)
.
TypeHandle
]
=
DbType
.
UInt64
;
typeMap
[
typeof
(
float
)
.
TypeHandle
]
=
DbType
.
Single
;
typeMap
[
typeof
(
double
)
.
TypeHandle
]
=
DbType
.
Double
;
typeMap
[
typeof
(
decimal
)
.
TypeHandle
]
=
DbType
.
Decimal
;
typeMap
[
typeof
(
bool
)
.
TypeHandle
]
=
DbType
.
Boolean
;
typeMap
[
typeof
(
string
)
.
TypeHandle
]
=
DbType
.
String
;
typeMap
[
typeof
(
char
)
.
TypeHandle
]
=
DbType
.
StringFixedLength
;
typeMap
[
typeof
(
Guid
)
.
TypeHandle
]
=
DbType
.
Guid
;
typeMap
[
typeof
(
DateTime
)
.
TypeHandle
]
=
DbType
.
DateTime
;
typeMap
[
typeof
(
DateTimeOffset
)
.
TypeHandle
]
=
DbType
.
DateTimeOffset
;
typeMap
[
typeof
(
byte
[])
.
TypeHandle
]
=
DbType
.
Binary
;
typeMap
[
typeof
(
byte
?)
.
TypeHandle
]
=
DbType
.
Byte
;
typeMap
[
typeof
(
sbyte
?)
.
TypeHandle
]
=
DbType
.
SByte
;
typeMap
[
typeof
(
short
?)
.
TypeHandle
]
=
DbType
.
Int16
;
typeMap
[
typeof
(
ushort
?)
.
TypeHandle
]
=
DbType
.
UInt16
;
typeMap
[
typeof
(
int
?)
.
TypeHandle
]
=
DbType
.
Int32
;
typeMap
[
typeof
(
uint
?)
.
TypeHandle
]
=
DbType
.
UInt32
;
typeMap
[
typeof
(
long
?)
.
TypeHandle
]
=
DbType
.
Int64
;
typeMap
[
typeof
(
ulong
?)
.
TypeHandle
]
=
DbType
.
UInt64
;
typeMap
[
typeof
(
float
?)
.
TypeHandle
]
=
DbType
.
Single
;
typeMap
[
typeof
(
double
?)
.
TypeHandle
]
=
DbType
.
Double
;
typeMap
[
typeof
(
decimal
?)
.
TypeHandle
]
=
DbType
.
Decimal
;
typeMap
[
typeof
(
bool
?)
.
TypeHandle
]
=
DbType
.
Boolean
;
typeMap
[
typeof
(
char
?)
.
TypeHandle
]
=
DbType
.
StringFixedLength
;
typeMap
[
typeof
(
Guid
?)
.
TypeHandle
]
=
DbType
.
Guid
;
typeMap
[
typeof
(
DateTime
?)
.
TypeHandle
]
=
DbType
.
DateTime
;
typeMap
[
typeof
(
DateTimeOffset
?)
.
TypeHandle
]
=
DbType
.
DateTimeOffset
;
}
private
static
DbType
LookupDbType
(
Type
type
)
{
DbType
dbType
;
if
(
typeMap
.
TryGetValue
(
type
,
out
dbType
))
if
(
typeMap
.
TryGetValue
(
type
.
TypeHandle
,
out
dbType
))
{
return
dbType
;
}
...
...
@@ -91,17 +92,12 @@ private static DbType LookupDbType(Type type)
private
class
Identity
:
IEquatable
<
Identity
>
{
public
String
ConnectionString
{
get
{
return
connectionString
;
}
}
public
Type
Type
{
get
{
return
type
;
}
}
public
string
Sql
{
get
{
return
sql
;
}
}
public
Type
ParametersType
{
get
{
return
ParametersType
;
}
}
internal
Identity
(
string
sql
,
IDbConnection
cnn
,
Type
type
,
Type
parametersType
,
Type
[]
otherTypes
=
null
)
{
this
.
sql
=
sql
;
this
.
connectionString
=
cnn
.
ConnectionString
;
this
.
type
=
type
;
this
.
parametersType
=
parametersType
;
this
.
otherTypes
=
otherTypes
;
unchecked
{
hashCode
=
17
;
// we *know* we are using this in a dictionary, so pre-compute this
...
...
@@ -125,7 +121,6 @@ public override bool Equals(object obj)
private
readonly
string
sql
;
private
readonly
int
hashCode
;
private
readonly
Type
type
;
private
readonly
Type
[]
otherTypes
;
private
readonly
string
connectionString
;
private
readonly
Type
parametersType
;
public
override
int
GetHashCode
()
...
...
@@ -184,7 +179,7 @@ public static GridReader QueryMultiple(this IDbConnection cnn, string sql, dynam
{
cmd
=
SetupCommand
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
,
commandTimeout
);
reader
=
cmd
.
ExecuteReader
();
return
new
GridReader
(
cmd
,
reader
,
cnn
,
sql
);
return
new
GridReader
(
cmd
,
reader
);
}
catch
{
...
...
@@ -208,7 +203,7 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
{
if
(
info
.
Deserializer
==
null
)
{
info
.
Deserializer
=
GetDeserializer
<
T
>(
identity
,
reader
);
info
.
Deserializer
=
GetDeserializer
<
T
>(
reader
);
queryCache
[
identity
]
=
info
;
}
...
...
@@ -274,7 +269,6 @@ class DontMap {}
{
if
(
info
.
Deserializer
==
null
)
{
var
split
=
0
;
int
current
=
0
;
Func
<
int
>
nextSplit
=
()
=>
...
...
@@ -294,31 +288,31 @@ class DontMap {}
var
otherDeserializer
=
new
List
<
object
>();
split
=
nextSplit
();
info
.
Deserializer
=
GetDeserializer
<
TFirst
>(
identity
,
reader
,
0
,
split
);
int
split
=
nextSplit
();
info
.
Deserializer
=
GetDeserializer
<
TFirst
>(
reader
,
0
,
split
);
if
(
typeof
(
TSecond
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TSecond
>(
identity
,
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TSecond
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
split
=
next
;
}
if
(
typeof
(
TThird
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TThird
>(
identity
,
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TThird
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
split
=
next
;
}
if
(
typeof
(
TFourth
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TFourth
>(
identity
,
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TFourth
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
split
=
next
;
}
if
(
typeof
(
TFifth
)
!=
typeof
(
DontMap
))
{
var
next
=
nextSplit
();
otherDeserializer
.
Add
(
GetDeserializer
<
TFifth
>(
identity
,
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
otherDeserializer
.
Add
(
GetDeserializer
<
TFifth
>(
reader
,
split
,
next
-
split
,
returnNullIfFirstMissing
:
true
));
}
info
.
OtherDeserializers
=
otherDeserializer
.
ToArray
();
...
...
@@ -391,26 +385,19 @@ private static CacheInfo GetCacheInfo(object param, Identity identity)
return
info
;
}
private
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
I
dentity
identity
,
I
DataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
private
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
{
object
oDeserializer
;
// dynamic is passed in as Object ... by c# design
if
(
typeof
(
T
)
==
typeof
(
object
)
||
typeof
(
T
)
==
typeof
(
FastExpando
))
{
oDeserializer
=
GetDynamicDeserializer
(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
);
}
else
if
(
typeof
(
T
).
IsClass
&&
typeof
(
T
)
!=
typeof
(
string
))
if
(
typeof
(
T
)
==
typeof
(
object
)
||
typeof
(
T
)
==
typeof
(
FastExpando
))
{
oDeserializer
=
GetClassDeserializer
<
T
>(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
:
returnNullIfFirstMissing
);
return
GetDynamicDeserializer
<
T
>(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
);
}
else
if
(
typeof
(
T
).
IsClass
&&
typeof
(
T
)
!=
typeof
(
string
))
{
oDeserializer
=
GetStructDeserializer
<
T
>(
reader
);
return
GetClassDeserializer
<
T
>(
reader
,
startBound
,
length
,
returnNullIfFirstMissing
);
}
return
GetStructDeserializer
<
T
>();
var
deserializer
=
(
Func
<
IDataReader
,
T
>)
oDeserializer
;
return
deserializer
;
}
private
class
FastExpando
:
DynamicObject
...
...
@@ -419,9 +406,7 @@ private class FastExpando : DynamicObject
public
static
FastExpando
Attach
(
IDictionary
<
string
,
object
>
data
)
{
FastExpando
expando
=
new
FastExpando
();
expando
.
data
=
data
;
return
expando
;
return
new
FastExpando
{
data
=
data
};
}
public
override
bool
TrySetMember
(
SetMemberBinder
binder
,
object
value
)
...
...
@@ -436,14 +421,14 @@ public override bool TryGetMember(GetMemberBinder binder, out object result)
}
}
private
static
object
GetDynamicDeserializer
(
IDataRecord
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
private
static
Func
<
IDataReader
,
T
>
GetDynamicDeserializer
<
T
>
(
IDataRecord
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
{
if
(
length
==
-
1
)
{
length
=
reader
.
FieldCount
-
startBound
;
}
Func
<
IDataReader
,
FastExpando
>
rval
=
return
r
=>
{
IDictionary
<
string
,
object
>
row
=
new
Dictionary
<
string
,
object
>(
length
);
...
...
@@ -454,13 +439,13 @@ private static object GetDynamicDeserializer(IDataRecord reader, int startBound
row
[
r
.
GetName
(
i
)]
=
tmp
;
if
(
returnNullIfFirstMissing
&&
i
==
startBound
&&
tmp
==
null
)
{
return
null
;
return
default
(
T
)
;
}
}
return
FastExpando
.
Attach
(
row
);
//we know this is an object so it will not box
return
(
T
)(
object
)
FastExpando
.
Attach
(
row
);
};
return
rval
;
}
[
Browsable
(
false
),
EditorBrowsable
(
EditorBrowsableState
.
Never
)]
[
Obsolete
(
"This method is for internal usage only"
,
true
)]
...
...
@@ -471,10 +456,10 @@ public static void PackListParameters(IDbCommand command, string namePrefix, obj
var
list
=
value
as
IEnumerable
;
var
count
=
0
;
bool
isString
=
value
is
IEnumerable
<
string
>;
if
(
list
!=
null
)
{
bool
isString
=
value
is
IEnumerable
<
string
>;
foreach
(
var
item
in
list
)
{
count
++;
...
...
@@ -660,11 +645,9 @@ private static int ExecuteCommand(IDbConnection cnn, IDbTransaction tranaction,
}
}
private
static
object
GetStructDeserializer
<
T
>(
IDataReader
reader
)
private
static
Func
<
IDataReader
,
T
>
GetStructDeserializer
<
T
>(
)
{
Func
<
IDataReader
,
T
>
deserializer
=
null
;
deserializer
=
r
=>
return
r
=>
{
var
val
=
r
.
GetValue
(
0
);
if
(
val
==
DBNull
.
Value
)
...
...
@@ -673,7 +656,6 @@ private static object GetStructDeserializer<T>(IDataReader reader)
}
return
(
T
)
val
;
};
return
deserializer
;
}
public
static
Func
<
IDataReader
,
T
>
GetClassDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
,
bool
returnNullIfFirstMissing
=
false
)
...
...
@@ -723,7 +705,7 @@ private static object GetStructDeserializer<T>(IDataReader reader)
int
index
=
startBound
;
var
@try
=
il
.
BeginExceptionBlock
();
il
.
BeginExceptionBlock
();
// stack is empty
il
.
Emit
(
OpCodes
.
Newobj
,
typeof
(
T
).
GetConstructor
(
Type
.
EmptyTypes
));
// stack is now [target]
bool
first
=
true
;
...
...
@@ -837,19 +819,10 @@ private static void EmitInt32(ILGenerator il, int value)
public
class
GridReader
:
IDisposable
{
private
IDataReader
reader
;
private
IDbConnection
connection
;
private
IDbCommand
command
;
private
readonly
string
sql
;
internal
GridReader
(
IDbCommand
command
,
IDataReader
reader
,
IDbConnection
connection
,
string
sql
)
internal
GridReader
(
IDbCommand
command
,
IDataReader
reader
)
{
if
(
reader
==
null
)
throw
new
ArgumentNullException
(
"reader"
);
if
(
connection
==
null
)
throw
new
ArgumentNullException
(
"connection"
);
if
(
sql
==
null
)
throw
new
ArgumentNullException
(
"sql"
);
if
(
command
==
null
)
throw
new
ArgumentNullException
(
"command"
);
this
.
sql
=
sql
;
this
.
command
=
command
;
this
.
connection
=
connection
;
this
.
reader
=
reader
;
}
/// <summary>
...
...
@@ -859,8 +832,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
identity
=
new
Identity
(
sql
,
connection
,
typeof
(
T
),
null
);
var
deserializer
=
SqlMapper
.
GetDeserializer
<
T
>(
identity
,
reader
);
var
deserializer
=
GetDeserializer
<
T
>(
reader
);
consumed
=
true
;
return
ReadDeferred
(
gridIndex
,
deserializer
);
}
...
...
@@ -901,7 +873,6 @@ private void NextResult()
}
public
void
Dispose
()
{
connection
=
null
;
if
(
reader
!=
null
)
{
reader
.
Dispose
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录