Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Dapper
提交
c4905c57
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,发现更多精彩内容 >>
提交
c4905c57
编写于
5月 12, 2015
作者:
J
Johan Danforth
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
New features in Dapper.Contrib
上级
24e55162
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
251 addition
and
38 deletion
+251
-38
Dapper.Contrib.Tests NET45/TestsAsync.cs
Dapper.Contrib.Tests NET45/TestsAsync.cs
+6
-6
Dapper.Contrib.Tests/Assert.cs
Dapper.Contrib.Tests/Assert.cs
+8
-0
Dapper.Contrib.Tests/Tests.cs
Dapper.Contrib.Tests/Tests.cs
+105
-8
Dapper.Contrib/Dapper.Contrib.csproj
Dapper.Contrib/Dapper.Contrib.csproj
+3
-0
Dapper.Contrib/Readme.md
Dapper.Contrib/Readme.md
+46
-17
Dapper.Contrib/SqlMapperExtensions.cs
Dapper.Contrib/SqlMapperExtensions.cs
+83
-7
未找到文件。
Dapper.Contrib.Tests NET45/TestsAsync.cs
浏览文件 @
c4905c57
...
...
@@ -44,7 +44,7 @@ public async Task TestSimpleGetAsync()
{
var
id
=
await
connection
.
InsertAsync
(
new
User
{
Name
=
"Adama"
,
Age
=
10
});
var
user
=
await
connection
.
GetAsync
<
User
>(
id
);
user
.
Id
.
IsEqualTo
((
int
)
id
);
user
.
The
Id
.
IsEqualTo
((
int
)
id
);
user
.
Name
.
IsEqualTo
(
"Adama"
);
await
connection
.
DeleteAsync
(
user
);
}
...
...
@@ -90,7 +90,7 @@ public async Task InsertCheckKeyAsync()
(
await
connection
.
GetAsync
<
IUser
>(
3
)).
IsNull
();
User
user
=
new
User
{
Name
=
"Adamb"
,
Age
=
10
};
int
id
=
(
int
)
await
connection
.
InsertAsync
(
user
);
user
.
Id
.
IsEqualTo
(
id
);
user
.
The
Id
.
IsEqualTo
(
id
);
}
}
...
...
@@ -102,9 +102,9 @@ public async Task BuilderSelectClauseAsync()
var
data
=
new
List
<
User
>();
for
(
int
i
=
0
;
i
<
100
;
i
++)
{
var
nU
=
new
User
{
Age
=
rand
.
Next
(
70
),
Id
=
i
,
Name
=
Guid
.
NewGuid
().
ToString
()
};
var
nU
=
new
User
{
Age
=
rand
.
Next
(
70
),
The
Id
=
i
,
Name
=
Guid
.
NewGuid
().
ToString
()
};
data
.
Add
(
nU
);
nU
.
Id
=
(
int
)
await
connection
.
InsertAsync
<
User
>(
nU
);
nU
.
The
Id
=
(
int
)
await
connection
.
InsertAsync
<
User
>(
nU
);
}
var
builder
=
new
SqlBuilder
();
...
...
@@ -118,8 +118,8 @@ public async Task BuilderSelectClauseAsync()
foreach
(
var
u
in
data
)
{
if
(!
ids
.
Any
(
i
=>
u
.
Id
==
i
))
throw
new
Exception
(
"Missing ids in select"
);
if
(!
users
.
Any
(
a
=>
a
.
Id
==
u
.
Id
&&
a
.
Name
==
u
.
Name
&&
a
.
Age
==
u
.
Age
))
throw
new
Exception
(
"Missing users in select"
);
if
(!
ids
.
Any
(
i
=>
u
.
The
Id
==
i
))
throw
new
Exception
(
"Missing ids in select"
);
if
(!
users
.
Any
(
a
=>
a
.
TheId
==
u
.
The
Id
&&
a
.
Name
==
u
.
Name
&&
a
.
Age
==
u
.
Age
))
throw
new
Exception
(
"Missing users in select"
);
}
}
}
...
...
Dapper.Contrib.Tests/Assert.cs
浏览文件 @
c4905c57
...
...
@@ -17,6 +17,14 @@ public static void IsEqualTo<T>(this T obj, T other)
}
}
public
static
void
IsMoreThan
(
this
int
obj
,
int
other
)
{
if
(
obj
<
other
)
{
throw
new
ApplicationException
(
string
.
Format
(
"{0} should be larger than {1}"
,
obj
,
other
));
}
}
public
static
void
IsSequenceEqualTo
<
T
>(
this
IEnumerable
<
T
>
obj
,
IEnumerable
<
T
>
other
)
{
if
(!
obj
.
SequenceEqual
(
other
))
...
...
Dapper.Contrib.Tests/Tests.cs
浏览文件 @
c4905c57
using
System.Data
;
using
System
;
using
System.Collections.Generic
;
using
System.Data
;
using
System.Data.SqlServerCe
;
using
System.IO
;
using
System.Linq
;
using
System.Reflection
;
using
System.Transactions
;
using
Dapper.Contrib.Extensions
;
using
System.Collections.Generic
;
using
System
;
namespace
Dapper.Contrib.Tests
{
...
...
@@ -90,10 +89,83 @@ public void TestSimpleGet()
}
}
public
void
InsertList
()
{
const
int
numberOfEntities
=
100
;
var
users
=
new
List
<
User
>();
for
(
var
i
=
0
;
i
<
numberOfEntities
;
i
++)
users
.
Add
(
new
User
{
Name
=
"User "
+
i
,
Age
=
i
});
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
var
total
=
connection
.
Insert
(
users
);
total
.
IsEqualTo
(
numberOfEntities
);
users
=
connection
.
Query
<
User
>(
"select * from users"
).
ToList
();
users
.
Count
.
IsEqualTo
(
numberOfEntities
);
}
}
public
void
UpdateList
()
{
const
int
numberOfEntities
=
100
;
var
users
=
new
List
<
User
>();
for
(
var
i
=
0
;
i
<
numberOfEntities
;
i
++)
users
.
Add
(
new
User
{
Name
=
"User "
+
i
,
Age
=
i
});
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
var
total
=
connection
.
Insert
(
users
);
total
.
IsEqualTo
(
numberOfEntities
);
users
=
connection
.
Query
<
User
>(
"select * from users"
).
ToList
();
users
.
Count
.
IsEqualTo
(
numberOfEntities
);
foreach
(
var
user
in
users
)
{
user
.
Name
=
user
.
Name
+
" updated"
;
}
connection
.
Update
(
users
);
var
name
=
connection
.
Query
<
User
>(
"select * from users"
).
First
().
Name
;
name
.
Contains
(
"updated"
).
IsTrue
();
}
}
public
void
DeleteList
()
{
const
int
numberOfEntities
=
100
;
var
users
=
new
List
<
User
>();
for
(
var
i
=
0
;
i
<
numberOfEntities
;
i
++)
users
.
Add
(
new
User
{
Name
=
"User "
+
i
,
Age
=
i
});
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
var
total
=
connection
.
Insert
(
users
);
total
.
IsEqualTo
(
numberOfEntities
);
users
=
connection
.
Query
<
User
>(
"select * from users"
).
ToList
();
users
.
Count
.
IsEqualTo
(
numberOfEntities
);
var
usersToDelete
=
users
.
Take
(
10
).
ToList
();
connection
.
Delete
(
usersToDelete
);
users
=
connection
.
Query
<
User
>(
"select * from users"
).
ToList
();
users
.
Count
.
IsEqualTo
(
numberOfEntities
-
10
);
}
}
public
void
InsertGetUpdate
()
{
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
connection
.
Get
<
User
>(
3
).
IsNull
();
//insert with computed attribute that should be ignored
...
...
@@ -123,9 +195,32 @@ public void InsertGetUpdate()
connection
.
Query
<
User
>(
"select * from Users"
).
Count
().
IsEqualTo
(
0
);
connection
.
Update
(
notrackedUser
).
IsEqualTo
(
false
);
//returns false, user not found
}
}
public
void
GetAll
()
{
const
int
numberOfEntities
=
100
;
var
users
=
new
List
<
User
>();
for
(
var
i
=
0
;
i
<
numberOfEntities
;
i
++)
users
.
Add
(
new
User
{
Name
=
"User "
+
i
,
Age
=
i
});
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
var
total
=
connection
.
Insert
(
users
);
total
.
IsEqualTo
(
numberOfEntities
);
users
=
connection
.
GetAll
<
User
>().
ToList
();
users
.
Count
.
IsEqualTo
(
numberOfEntities
);
var
iusers
=
connection
.
GetAll
<
IUser
>().
ToList
();
iusers
.
Count
.
IsEqualTo
(
numberOfEntities
);
}
}
public
void
Transactions
()
{
using
(
var
connection
=
GetOpenConnection
())
...
...
@@ -182,7 +277,7 @@ public void BuilderSelectClause()
{
var
nU
=
new
User
{
Age
=
rand
.
Next
(
70
),
Id
=
i
,
Name
=
Guid
.
NewGuid
().
ToString
()
};
data
.
Add
(
nU
);
nU
.
Id
=
(
int
)
connection
.
Insert
<
User
>
(
nU
);
nU
.
Id
=
(
int
)
connection
.
Insert
(
nU
);
}
var
builder
=
new
SqlBuilder
();
...
...
@@ -212,6 +307,7 @@ public void BuilderTemplateWOComposition()
using
(
var
connection
=
GetOpenConnection
())
{
connection
.
DeleteAll
<
User
>();
connection
.
Insert
(
new
User
{
Age
=
5
,
Name
=
"Testy McTestington"
});
if
(
connection
.
Query
<
int
>(
template
.
RawSql
,
template
.
Parameters
).
Single
()
!=
1
)
...
...
@@ -221,11 +317,12 @@ public void BuilderTemplateWOComposition()
public
void
InsertFieldWithReservedName
()
{
using
(
var
connec
it
on
=
GetOpenConnection
())
using
(
var
connec
ti
on
=
GetOpenConnection
())
{
var
id
=
conneciton
.
Insert
(
new
Result
()
{
Name
=
"Adam"
,
Order
=
1
});
connection
.
DeleteAll
<
User
>();
var
id
=
connection
.
Insert
(
new
Result
()
{
Name
=
"Adam"
,
Order
=
1
});
var
result
=
connec
it
on
.
Get
<
Result
>(
id
);
var
result
=
connec
ti
on
.
Get
<
Result
>(
id
);
result
.
Order
.
IsEqualTo
(
1
);
}
...
...
Dapper.Contrib/Dapper.Contrib.csproj
浏览文件 @
c4905c57
...
...
@@ -59,6 +59,9 @@
<Name>
Dapper NET40
</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None
Include=
"Readme.md"
/>
</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.
...
...
Dapper.Contrib/Readme.md
浏览文件 @
c4905c57
...
...
@@ -5,58 +5,87 @@ Features
--------
Dapper.Contrib contains a number of helper methods for inserting, getting, updating and deleting files.
The object you are working with must have a property named Id or a property marked with a [Key] attribute. As with dapper,
all extension methods assume the connection is already open, they will fail if the connection is closed.
As with dapper, all extension methods assume the connection is already open, they will fail if the
connection is closed. The full list of extension methods in Dapper.Contrib right now are:
Inserts
-------
```
csharp
public
static
long
Insert
<
T
>(
this
IDbConnection
connection
,
T
entityToInsert
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
T
Get
<
T
>(
id
);
IEnumerable
<
T
>
GetAll
<
T
>();
int
Insert
<
T
>(
T
obj
);
int
Insert
<
T
>(
Enumerable
<
T
>
list
);
bool
Update
<
T
>(
T
obj
);
bool
Update
<
T
>(
Enumerable
<
T
>
list
);
bool
Delete
<
T
>(
T
obj
);
bool
Delete
<
T
>(
Enumerable
<
T
>
list
);
bool
DeleteAll
<
T
>();
```
For these extensions to work, the entity in question _MUST_ have a key-property, a property named "id" or decorated with
a [Key] attribute.
```
csharp
public
class
Car
{
public
int
Id
{
get
;
set
;
}
public
string
Name
{
get
;
set
;
}
}
connection
.
Insert
(
new
Car
{
Name
=
"Volvo"
});
public
class
User
{
[
Key
]
int
TheId
{
get
;
set
;
}
string
Name
{
get
;
set
;
}
int
Age
{
get
;
set
;
}
}
```
Gets
-------
```
csharp
public
static
T
Get
<
T
>(
this
IDbConnection
connection
,
dynamic
id
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
```
Get one specific entity based on id, or a list of all entities in the table.
```
csharp
var
car
=
connection
.
Get
<
Car
>(
1
);
var
cars
=
connection
.
GetAll
<
Car
>();
```
Update
s
Insert
s
-------
Insert one entity or a list of entities.
```
csharp
public
static
bool
Update
<
T
>(
this
IDbConnection
connection
,
T
entityToUpdate
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
connection
.
Insert
(
new
Car
{
Name
=
"Volvo"
});
connection
.
Insert
(
cars
);
```
Updates
-------
Update one specific entity or update a list of entities.
```
csharp
connection
.
Update
(
new
Car
()
{
Id
=
1
,
Name
=
"Saab"
});
connection
.
Update
(
cars
);
```
Deletes
-------
```
csharp
public
static
bool
Delete
<
T
>(
this
IDbConnection
connection
,
T
entityToDelete
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
public
static
bool
DeleteAll
<
T
>(
this
IDbConnection
connection
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
```
Delete one specific entity, a list of entities, or _ALL_ entities in the table.
```
csharp
connection
.
Delete
(
new
Car
()
{
Id
=
1
});
connection
.
Delete
(
cars
);
connection
.
DeleteAll
<
Car
>();
```
Attributes
Special
Attributes
----------
Dapper.Contrib makes use of some optional attributes:
...
...
Dapper.Contrib/SqlMapperExtensions.cs
浏览文件 @
c4905c57
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Data
;
using
System.Linq
;
...
...
@@ -109,6 +110,7 @@ private static bool IsWriteable(PropertyInfo pi)
public
static
T
Get
<
T
>(
this
IDbConnection
connection
,
dynamic
id
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
where
T
:
class
{
var
type
=
typeof
(
T
);
string
sql
;
if
(!
GetQueries
.
TryGetValue
(
type
.
TypeHandle
,
out
sql
))
{
...
...
@@ -122,7 +124,6 @@ private static bool IsWriteable(PropertyInfo pi)
var
name
=
GetTableName
(
type
);
// TODO: pluralizer
// TODO: query information schema and only select fields that are both in information schema and underlying class / interface
sql
=
"select * from "
+
name
+
" where "
+
onlyKey
.
Name
+
" = @id"
;
GetQueries
[
type
.
TypeHandle
]
=
sql
;
...
...
@@ -156,6 +157,58 @@ private static bool IsWriteable(PropertyInfo pi)
}
return
obj
;
}
/// <summary>
/// Returns a list of entites from table "Ts".
/// Id of T must be marked with [Key] attribute.
/// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension
/// for optimal performance.
/// </summary>
/// <typeparam name="T">Interface or type to create and populate</typeparam>
/// <param name="connection">Open SqlConnection</param>
/// <returns>Entity of T</returns>
public
static
IEnumerable
<
T
>
GetAll
<
T
>(
this
IDbConnection
connection
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
where
T
:
class
{
var
type
=
typeof
(
T
);
var
cacheType
=
typeof
(
List
<
T
>);
string
sql
;
if
(!
GetQueries
.
TryGetValue
(
cacheType
.
TypeHandle
,
out
sql
))
{
var
keys
=
KeyPropertiesCache
(
type
);
if
(
keys
.
Count
()
>
1
)
throw
new
DataException
(
"Get<T> only supports an entity with a single [Key] property"
);
if
(!
keys
.
Any
())
throw
new
DataException
(
"Get<T> only supports en entity with a [Key] property"
);
var
onlyKey
=
keys
.
First
();
var
name
=
GetTableName
(
type
);
// TODO: query information schema and only select fields that are both in information schema and underlying class / interface
sql
=
"select * from "
+
name
;
GetQueries
[
cacheType
.
TypeHandle
]
=
sql
;
}
if
(!
type
.
IsInterface
)
return
connection
.
Query
<
T
>(
sql
,
null
,
transaction
,
commandTimeout
:
commandTimeout
);
var
result
=
connection
.
Query
(
sql
);
var
list
=
new
List
<
T
>();
foreach
(
IDictionary
<
string
,
object
>
res
in
result
)
{
var
obj
=
ProxyGenerator
.
GetInterfaceProxy
<
T
>();
foreach
(
var
property
in
TypePropertiesCache
(
type
))
{
var
val
=
res
[
property
.
Name
];
property
.
SetValue
(
obj
,
val
,
null
);
}
((
IProxy
)
obj
).
IsDirty
=
false
;
//reset change tracking and return
list
.
Add
(
obj
);
}
return
list
;
}
private
static
string
GetTableName
(
Type
type
)
{
string
name
;
...
...
@@ -176,14 +229,23 @@ private static string GetTableName(Type type)
}
/// <summary>
/// Inserts an entity into table "Ts" and returns identity id.
/// Inserts an entity into table "Ts" and returns identity id
or number if inserted rows if inserting a list
.
/// </summary>
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert</param>
/// <returns>Identity of inserted entity</returns>
/// <param name="entityToInsert">Entity to insert
, can be list of entities
</param>
/// <returns>Identity of inserted entity
, or number of inserted rows if inserting a list
</returns>
public
static
long
Insert
<
T
>(
this
IDbConnection
connection
,
T
entityToInsert
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
where
T
:
class
{
var
isList
=
false
;
var
type
=
typeof
(
T
);
if
(
type
.
IsArray
||
type
.
IsGenericType
)
{
isList
=
true
;
type
=
type
.
GetGenericArguments
()[
0
];
}
var
name
=
GetTableName
(
type
);
var
sbColumnList
=
new
StringBuilder
(
null
);
var
allProperties
=
TypePropertiesCache
(
type
);
...
...
@@ -207,9 +269,17 @@ private static string GetTableName(Type type)
if
(
i
<
allPropertiesExceptKeyAndComputed
.
Count
()
-
1
)
sbParameterList
.
Append
(
", "
);
}
var
adapter
=
GetFormatter
(
connection
);
return
adapter
.
Insert
(
connection
,
transaction
,
commandTimeout
,
name
,
sbColumnList
.
ToString
(),
sbParameterList
.
ToString
(),
keyProperties
,
entityToInsert
);
if
(!
isList
)
//single entity
{
var
adapter
=
GetFormatter
(
connection
);
return
adapter
.
Insert
(
connection
,
transaction
,
commandTimeout
,
name
,
sbColumnList
.
ToString
(),
sbParameterList
.
ToString
(),
keyProperties
,
entityToInsert
);
}
//insert list of entities
var
cmd
=
String
.
Format
(
"insert into {0} ({1}) values ({2})"
,
name
,
sbColumnList
,
sbParameterList
);
return
connection
.
Execute
(
cmd
,
entityToInsert
,
transaction
,
commandTimeout
);
}
/// <summary>
...
...
@@ -229,6 +299,9 @@ private static string GetTableName(Type type)
var
type
=
typeof
(
T
);
if
(
type
.
IsArray
||
type
.
IsGenericType
)
type
=
type
.
GetGenericArguments
()[
0
];
var
keyProperties
=
KeyPropertiesCache
(
type
);
if
(!
keyProperties
.
Any
())
throw
new
ArgumentException
(
"Entity must have at least one [Key] property"
);
...
...
@@ -275,6 +348,9 @@ private static string GetTableName(Type type)
var
type
=
typeof
(
T
);
if
(
type
.
IsArray
||
type
.
IsGenericType
)
type
=
type
.
GetGenericArguments
()[
0
];
var
keyProperties
=
KeyPropertiesCache
(
type
);
if
(!
keyProperties
.
Any
())
throw
new
ArgumentException
(
"Entity must have at least one [Key] property"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录