Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Dapper
提交
b7c73515
D
Dapper
项目概览
int
/
Dapper
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
b7c73515
编写于
4月 24, 2011
作者:
S
Sam Saffron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implemented simple join multimap
上级
4ca04f91
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
80 addition
and
14 deletion
+80
-14
Dapper/SqlMapper.cs
Dapper/SqlMapper.cs
+64
-13
Tests/Tests.cs
Tests/Tests.cs
+16
-1
未找到文件。
Dapper/SqlMapper.cs
浏览文件 @
b7c73515
...
...
@@ -21,6 +21,7 @@ public static class SqlMapper
class
CacheInfo
{
public
object
Deserializer
{
get
;
set
;
}
public
object
Deserializer2
{
get
;
set
;
}
public
Action
<
IDbCommand
,
object
>
ParamReader
{
get
;
set
;
}
}
...
...
@@ -90,19 +91,22 @@ private class Identity : IEquatable<Identity>
public
String
ConnectionString
{
get
{
return
connectionString
;
}
}
public
Type
Type
{
get
{
return
type
;
}
}
public
Type
Type2
{
get
{
return
Type2
;
}
}
public
string
Sql
{
get
{
return
sql
;
}
}
public
Type
ParametersType
{
get
{
return
ParametersType
;
}
}
internal
Identity
(
string
sql
,
IDbConnection
cnn
,
Type
type
,
Type
parametersType
)
internal
Identity
(
string
sql
,
IDbConnection
cnn
,
Type
type
,
Type
parametersType
,
Type
type2
=
null
)
{
this
.
sql
=
sql
;
this
.
connectionString
=
cnn
.
ConnectionString
;
this
.
type
=
type
;
this
.
parametersType
=
parametersType
;
this
.
type2
=
type2
;
unchecked
{
hashCode
=
17
;
// we *know* we are using this in a dictionary, so pre-compute this
hashCode
=
hashCode
*
23
+
(
sql
==
null
?
0
:
sql
.
GetHashCode
());
hashCode
=
hashCode
*
23
+
(
type
==
null
?
0
:
type
.
GetHashCode
());
hashCode
=
hashCode
*
23
+
(
type2
==
null
?
0
:
type2
.
GetHashCode
());
hashCode
=
hashCode
*
23
+
(
connectionString
==
null
?
0
:
connectionString
.
GetHashCode
());
hashCode
=
hashCode
*
23
+
(
parametersType
==
null
?
0
:
parametersType
.
GetHashCode
());
}
...
...
@@ -114,6 +118,7 @@ public override bool Equals(object obj)
private
readonly
string
sql
;
private
readonly
int
hashCode
;
private
readonly
Type
type
;
private
readonly
Type
type2
;
private
readonly
string
connectionString
;
private
readonly
Type
parametersType
;
public
override
int
GetHashCode
()
...
...
@@ -171,10 +176,8 @@ public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object
private
static
IEnumerable
<
T
>
QueryInternal
<
T
>(
this
IDbConnection
cnn
,
string
sql
,
object
param
=
null
,
IDbTransaction
transaction
=
null
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
T
),
param
==
null
?
null
:
param
.
GetType
());
var
info
=
GetCacheInfo
(
param
,
identity
);
using
(
var
reader
=
GetReader
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
))
{
if
(
info
.
Deserializer
==
null
)
...
...
@@ -190,7 +193,55 @@ private static IEnumerable<T> QueryInternal<T>(this IDbConnection cnn, string sq
yield
return
deserializer
(
reader
);
}
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="U"></typeparam>
/// <param name="cnn"></param>
/// <param name="sql"></param>
/// <param name="map"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="splitOn">The Field we should split and read the second object from (default: id)</param>
/// <returns></returns>
public
static
IEnumerable
<
T
>
Query
<
T
,
U
>(
this
IDbConnection
cnn
,
string
sql
,
Action
<
T
,
U
>
map
,
object
param
=
null
,
IDbTransaction
transaction
=
null
,
bool
buffered
=
true
,
string
splitOn
=
"Id"
)
{
var
identity
=
new
Identity
(
sql
,
cnn
,
typeof
(
T
),
param
==
null
?
null
:
param
.
GetType
());
var
info
=
GetCacheInfo
(
param
,
identity
);
using
(
var
reader
=
GetReader
(
cnn
,
transaction
,
sql
,
info
.
ParamReader
,
param
))
{
if
(
info
.
Deserializer
==
null
)
{
int
start
=
0
;
int
length
=
-
1
;
for
(
length
=
1
;
length
<
reader
.
FieldCount
;
length
++)
{
if
(
reader
.
GetName
(
length
)
==
splitOn
)
{
break
;
}
}
info
.
Deserializer
=
GetDeserializer
<
T
>(
identity
,
reader
,
start
,
length
);
info
.
Deserializer2
=
GetDeserializer
<
U
>(
identity
,
reader
,
start
+
length
);
queryCache
[
identity
]
=
info
;
}
var
deserializer
=
(
Func
<
IDataReader
,
T
>)
info
.
Deserializer
;
var
deserializer2
=
(
Func
<
IDataReader
,
U
>)
info
.
Deserializer2
;
while
(
reader
.
Read
())
{
var
tmp
=
deserializer
(
reader
);
map
(
tmp
,
deserializer2
(
reader
));
yield
return
tmp
;
}
}
}
private
static
CacheInfo
GetCacheInfo
(
object
param
,
Identity
identity
)
...
...
@@ -207,18 +258,13 @@ private static CacheInfo GetCacheInfo(object param, Identity identity)
return
info
;
}
public
static
List
<
T
>
Query
<
T
,
U
>(
this
IDbConnection
cnn
,
string
sql
,
Action
<
T
,
U
>
map
,
object
param
=
null
,
IDbTransaction
transaction
=
null
)
{
return
null
;
}
static
class
DynamicStub
{
public
static
Type
Type
=
typeof
(
DynamicStub
);
}
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
Identity
identity
,
IDataReader
reader
)
static
Func
<
IDataReader
,
T
>
GetDeserializer
<
T
>(
Identity
identity
,
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
)
{
object
oDeserializer
;
...
...
@@ -228,7 +274,7 @@ static class DynamicStub
}
else
if
(
typeof
(
T
).
IsClass
&&
typeof
(
T
)
!=
typeof
(
string
))
{
oDeserializer
=
GetClassDeserializer
<
T
>(
reader
);
oDeserializer
=
GetClassDeserializer
<
T
>(
reader
,
startBound
,
length
);
}
else
{
...
...
@@ -475,7 +521,7 @@ private static object GetStructDeserializer<T>(IDataReader reader)
return
deserializer
;
}
public
static
Func
<
IDataReader
,
T
>
GetClassDeserializer
<
T
>(
IDataReader
reader
)
public
static
Func
<
IDataReader
,
T
>
GetClassDeserializer
<
T
>(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
)
{
DynamicMethod
dm
=
new
DynamicMethod
(
"Deserialize"
+
Guid
.
NewGuid
().
ToString
(),
typeof
(
T
),
new
Type
[]
{
typeof
(
IDataReader
)
},
true
);
...
...
@@ -487,8 +533,13 @@ private static object GetStructDeserializer<T>(IDataReader reader)
.
Where
(
info
=>
info
.
Setter
!=
null
)
.
ToList
();
if
(
length
==
-
1
)
{
length
=
reader
.
FieldCount
-
startBound
;
}
var
names
=
new
List
<
string
>();
for
(
int
i
=
0
;
i
<
reader
.
FieldCount
;
i
++)
for
(
int
i
=
startBound
;
i
<
startBound
+
length
;
i
++)
{
names
.
Add
(
reader
.
GetName
(
i
));
}
...
...
@@ -505,7 +556,7 @@ private static object GetStructDeserializer<T>(IDataReader reader)
.
Where
(
p
=>
p
.
GetIndexParameters
().
Any
()
&&
p
.
GetIndexParameters
()[
0
].
ParameterType
==
typeof
(
int
))
.
Select
(
p
=>
p
.
GetGetMethod
()).
First
();
int
index
=
0
;
int
index
=
startBound
;
// stack is empty
il
.
Emit
(
OpCodes
.
Newobj
,
typeof
(
T
).
GetConstructor
(
Type
.
EmptyTypes
));
// stack is now [target]
...
...
Tests/Tests.cs
浏览文件 @
b7c73515
...
...
@@ -251,8 +251,23 @@ class Post
}
public
void
TestMultiMap
()
{
var
createSql
=
@"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20))
var
test
=
connection
.
Query
<
Post
,
User
>(
"select * from Posts p left join Users u on u.Id = p.OwnerId"
,
(
post
,
user
)
=>
{
post
.
Owner
=
user
;
});
insert #Users values(1, 'Sam')
insert #Users values(2, 'I am')
insert #Posts values(1, 1, 'Sams Post1')
insert #Posts values(2, 1, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
"
;
connection
.
Execute
(
createSql
);
var
data
=
connection
.
Query
<
Post
,
User
>(
"select * from #Posts p left join #Users u on u.Id = p.OwnerId Order by p.Id"
,
(
post
,
user
)
=>
{
post
.
Owner
=
user
;
});
data
.
First
().
Content
.
IsEqualTo
(
"Sams Post1"
);
data
.
First
().
Owner
.
Name
.
IsEqualTo
(
"Sam"
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录