Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Dapper
提交
bce25285
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,发现更多精彩内容 >>
提交
bce25285
编写于
1月 22, 2012
作者:
S
Sam
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #15 from greygeek/master
Added postresql support for Insert to return primary key of inserted row.
上级
e9d167e9
d57970fb
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
99 addition
and
20 deletion
+99
-20
Dapper.Contrib/SqlMapperExtensions.cs
Dapper.Contrib/SqlMapperExtensions.cs
+99
-20
未找到文件。
Dapper.Contrib/SqlMapperExtensions.cs
浏览文件 @
bce25285
...
...
@@ -9,6 +9,7 @@
using
System.Reflection.Emit
;
using
System.Threading
;
using
System.Runtime.CompilerServices
;
using
Dapper
;
namespace
Dapper.Contrib.Extensions
{
...
...
@@ -25,6 +26,11 @@ public interface IProxy
private
static
readonly
ConcurrentDictionary
<
RuntimeTypeHandle
,
string
>
GetQueries
=
new
ConcurrentDictionary
<
RuntimeTypeHandle
,
string
>();
private
static
readonly
ConcurrentDictionary
<
RuntimeTypeHandle
,
string
>
TypeTableName
=
new
ConcurrentDictionary
<
RuntimeTypeHandle
,
string
>();
private
static
readonly
Dictionary
<
string
,
ISqlAdapter
>
AdapterDictionary
=
new
Dictionary
<
string
,
ISqlAdapter
>()
{
{
"sqlconnection"
,
new
SqlServerAdapter
()},
{
"npgsqlconnection"
,
new
PostgresAdapter
()}
};
private
static
IEnumerable
<
PropertyInfo
>
KeyPropertiesCache
(
Type
type
)
{
...
...
@@ -57,12 +63,23 @@ private static IEnumerable<PropertyInfo> TypePropertiesCache(Type type)
return
pis
;
}
var
properties
=
type
.
GetProperties
();
var
properties
=
type
.
GetProperties
()
.
Where
(
IsWriteable
)
;
TypeProperties
[
type
.
TypeHandle
]
=
properties
;
return
properties
;
}
/// <summary>
public
static
bool
IsWriteable
(
PropertyInfo
pi
)
{
object
[]
attributes
=
pi
.
GetCustomAttributes
(
typeof
(
WriteAttribute
),
false
);
if
(
attributes
.
Length
==
1
)
{
WriteAttribute
write
=
(
WriteAttribute
)
attributes
[
0
];
return
write
.
Write
;
}
return
true
;
}
/// <summary>
/// Returns a single entity by a single id from table "Ts". T must be of interface type.
/// Id must be marked with [Key] attribute.
/// Created entity is tracked/intercepted for changes and used by the Update() extension.
...
...
@@ -148,41 +165,37 @@ private static string GetTableName(Type type)
/// <param name="entityToInsert">Entity to insert</param>
/// <returns>Identity of inserted entity</returns>
public
static
long
Insert
<
T
>(
this
IDbConnection
connection
,
T
entityToInsert
,
IDbTransaction
transaction
=
null
,
int
?
commandTimeout
=
null
)
where
T
:
class
{
{
var
type
=
typeof
(
T
);
var
name
=
GetTableName
(
type
);
var
sb
=
new
StringBuilder
(
null
);
sb
.
AppendFormat
(
"insert into {0} ("
,
name
);
var
sbColumnList
=
new
StringBuilder
(
null
);
var
allProperties
=
TypePropertiesCache
(
type
);
var
allProperties
=
TypePropertiesCache
(
type
);
var
keyProperties
=
KeyPropertiesCache
(
type
);
var
allPropertiesExceptKey
=
allProperties
.
Except
(
keyProperties
);
for
(
var
i
=
0
;
i
<
allPropertiesExceptKey
.
Count
();
i
++)
{
var
property
=
allPropertiesExceptKey
.
ElementAt
(
i
);
sb
.
Append
(
property
.
Name
);
sbColumnList
.
Append
(
property
.
Name
);
if
(
i
<
allPropertiesExceptKey
.
Count
()
-
1
)
sb
.
Append
(
", "
);
sbColumnList
.
Append
(
", "
);
}
sb
.
Append
(
") values ("
);
for
(
var
i
=
0
;
i
<
allPropertiesExceptKey
.
Count
();
i
++)
var
sbParameterList
=
new
StringBuilder
(
null
);
for
(
var
i
=
0
;
i
<
allPropertiesExceptKey
.
Count
();
i
++)
{
var
property
=
allPropertiesExceptKey
.
ElementAt
(
i
);
sb
.
AppendFormat
(
"@{0}"
,
property
.
Name
);
sb
ParameterList
.
AppendFormat
(
"@{0}"
,
property
.
Name
);
if
(
i
<
allPropertiesExceptKey
.
Count
()
-
1
)
sb
.
Append
(
", "
);
sb
ParameterList
.
Append
(
", "
);
}
sb
.
Append
(
") "
);
connection
.
Execute
(
sb
.
ToString
(),
entityToInsert
,
transaction
:
transaction
,
commandTimeout
:
commandTimeout
);
//NOTE: would prefer to use IDENT_CURRENT('tablename') or IDENT_SCOPE but these are not available on SQLCE
var
r
=
connection
.
Query
(
"select @@IDENTITY id"
,
transaction
:
transaction
,
commandTimeout
:
commandTimeout
);
return
(
int
)
r
.
First
().
id
;
ISqlAdapter
adapter
=
GetFormatter
(
connection
);
int
id
=
adapter
.
Insert
(
connection
,
transaction
,
commandTimeout
,
name
,
sbColumnList
.
ToString
(),
sbParameterList
.
ToString
(),
keyProperties
,
entityToInsert
);
return
id
;
}
/// <summary>
...
...
@@ -203,7 +216,7 @@ private static string GetTableName(Type type)
var
type
=
typeof
(
T
);
var
keyProperties
=
KeyPropertiesCache
(
type
);
if
(
keyProperties
.
Count
()
==
0
)
if
(
!
keyProperties
.
Any
()
)
throw
new
ArgumentException
(
"Entity must have at least one [Key] property"
);
var
name
=
GetTableName
(
type
);
...
...
@@ -264,8 +277,15 @@ private static string GetTableName(Type type)
return
deleted
>
0
;
}
public
static
ISqlAdapter
GetFormatter
(
IDbConnection
connection
)
{
string
name
=
connection
.
GetType
().
Name
.
ToLower
();
if
(!
AdapterDictionary
.
ContainsKey
(
name
))
return
new
SqlServerAdapter
();
return
AdapterDictionary
[
name
];
}
class
ProxyGenerator
class
ProxyGenerator
{
private
static
readonly
Dictionary
<
Type
,
object
>
TypeCache
=
new
Dictionary
<
Type
,
object
>();
...
...
@@ -440,4 +460,63 @@ public class KeyAttribute : Attribute
{
}
[
AttributeUsage
(
AttributeTargets
.
Property
)]
public
class
WriteAttribute
:
Attribute
{
public
WriteAttribute
(
bool
write
)
{
Write
=
write
;
}
public
bool
Write
{
get
;
private
set
;
}
}
}
public
interface
ISqlAdapter
{
int
Insert
(
IDbConnection
connection
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
String
tableName
,
string
columnList
,
string
parameterList
,
IEnumerable
<
PropertyInfo
>
keyProperties
,
object
entityToInsert
);
}
public
class
SqlServerAdapter
:
ISqlAdapter
{
public
int
Insert
(
IDbConnection
connection
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
String
tableName
,
string
columnList
,
string
parameterList
,
IEnumerable
<
PropertyInfo
>
keyProperties
,
object
entityToInsert
)
{
string
cmd
=
String
.
Format
(
"insert into {0} ({1}) values ({2})"
,
tableName
,
columnList
,
parameterList
);
connection
.
Execute
(
cmd
,
entityToInsert
,
transaction
:
transaction
,
commandTimeout
:
commandTimeout
);
//NOTE: would prefer to use IDENT_CURRENT('tablename') or IDENT_SCOPE but these are not available on SQLCE
var
r
=
connection
.
Query
(
"select @@IDENTITY id"
,
transaction
:
transaction
,
commandTimeout
:
commandTimeout
);
return
(
int
)
r
.
First
().
id
;
}
}
public
class
PostgresAdapter
:
ISqlAdapter
{
public
int
Insert
(
IDbConnection
connection
,
IDbTransaction
transaction
,
int
?
commandTimeout
,
String
tableName
,
string
columnList
,
string
parameterList
,
IEnumerable
<
PropertyInfo
>
keyProperties
,
object
entityToInsert
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
AppendFormat
(
"insert into {0} ({1}) values ({2})"
,
tableName
,
columnList
,
parameterList
);
sb
.
Append
(
" RETURNING "
);
bool
first
=
true
;
foreach
(
var
property
in
keyProperties
)
{
if
(!
first
)
sb
.
Append
(
", "
);
first
=
false
;
sb
.
Append
(
property
.
Name
);
}
var
results
=
connection
.
Query
(
sb
.
ToString
(),
entityToInsert
,
transaction
:
transaction
,
commandTimeout
:
commandTimeout
);
// Return the key by assinging the corresponding property in the object - by product is that it supports compound primary keys
int
id
=
0
;
foreach
(
var
p
in
keyProperties
)
{
var
value
=
((
IDictionary
<
string
,
object
>)
results
.
First
())[
p
.
Name
.
ToLower
()];
p
.
SetValue
(
entityToInsert
,
value
,
null
);
if
(
id
==
0
)
id
=
Convert
.
ToInt32
(
value
);
}
return
id
;
}
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录