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
9e67f97f
Commit
9e67f97f
authored
Aug 21, 2017
by
Nick Craver
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/StackExchange/Dapper
parents
7b34be3a
967a4a0a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
40 additions
and
18 deletions
+40
-18
SqlMapper.cs
Dapper/SqlMapper.cs
+40
-18
No files found.
Dapper/SqlMapper.cs
View file @
9e67f97f
...
...
@@ -30,6 +30,10 @@ namespace Dapper
/// </summary>
public
static
partial
class
SqlMapper
{
private
class
PropertyInfoByNameComparer
:
IComparer
<
PropertyInfo
>
{
public
int
Compare
(
PropertyInfo
x
,
PropertyInfo
y
)
=>
string
.
CompareOrdinal
(
x
.
Name
,
y
.
Name
);
}
private
static
int
GetColumnHash
(
IDataReader
reader
,
int
startBound
=
0
,
int
length
=
-
1
)
{
unchecked
...
...
@@ -2217,7 +2221,13 @@ public static object SanitizeParameterValue(object value)
private
static
IEnumerable
<
PropertyInfo
>
FilterParameters
(
IEnumerable
<
PropertyInfo
>
parameters
,
string
sql
)
{
return
parameters
.
Where
(
p
=>
Regex
.
IsMatch
(
sql
,
"[?@:]"
+
p
.
Name
+
@"([^\p{L}\p{N}_]+|$)"
,
RegexOptions
.
IgnoreCase
|
RegexOptions
.
Multiline
|
RegexOptions
.
CultureInvariant
));
var
list
=
new
List
<
PropertyInfo
>(
16
);
foreach
(
var
p
in
parameters
)
{
if
(
Regex
.
IsMatch
(
sql
,
@"[?@:]"
+
p
.
Name
+
@"([^\p{L}\p{N}_]+|$)"
,
RegexOptions
.
IgnoreCase
|
RegexOptions
.
Multiline
|
RegexOptions
.
CultureInvariant
))
list
.
Add
(
p
);
}
return
list
;
}
// look for ? / @ / : *by itself*
...
...
@@ -2356,7 +2366,7 @@ internal static IList<LiteralToken> GetLiteralTokens(string sql)
public
static
Action
<
IDbCommand
,
object
>
CreateParamInfoGenerator
(
Identity
identity
,
bool
checkForDuplicates
,
bool
removeUnused
)
=>
CreateParamInfoGenerator
(
identity
,
checkForDuplicates
,
removeUnused
,
GetLiteralTokens
(
identity
.
sql
));
private
static
bool
IsValueTuple
(
Type
type
)
=>
type
?.
IsValueType
()
==
true
&&
type
.
FullName
.
StartsWith
(
"System.ValueTuple`"
);
private
static
bool
IsValueTuple
(
Type
type
)
=>
type
?.
IsValueType
()
==
true
&&
type
.
FullName
.
StartsWith
(
"System.ValueTuple`"
,
StringComparison
.
Ordinal
);
private
static
List
<
IMemberMap
>
GetValueTupleMembers
(
Type
type
,
string
[]
names
)
{
...
...
@@ -2415,19 +2425,27 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
il
.
Emit
(
OpCodes
.
Ldarg_0
);
// stack is now [command]
il
.
EmitCall
(
OpCodes
.
Callvirt
,
typeof
(
IDbCommand
).
GetProperty
(
nameof
(
IDbCommand
.
Parameters
)).
GetGetMethod
(),
null
);
// stack is now [parameters]
var
propsArr
=
type
.
GetProperties
().
Where
(
p
=>
p
.
GetIndexParameters
().
Length
==
0
).
ToArray
();
var
allTypeProps
=
type
.
GetProperties
();
var
propsList
=
new
List
<
PropertyInfo
>(
allTypeProps
.
Length
);
for
(
int
i
=
0
;
i
<
allTypeProps
.
Length
;
++
i
)
{
var
p
=
allTypeProps
[
i
];
if
(
p
.
GetIndexParameters
().
Length
==
0
)
propsList
.
Add
(
p
);
}
var
ctors
=
type
.
GetConstructors
();
ParameterInfo
[]
ctorParams
;
IEnumerable
<
PropertyInfo
>
props
=
null
;
// try to detect tuple patterns, e.g. anon-types, and use that to choose the order
// otherwise: alphabetical
if
(
ctors
.
Length
==
1
&&
props
Arr
.
Length
==
(
ctorParams
=
ctors
[
0
].
GetParameters
()).
Length
)
if
(
ctors
.
Length
==
1
&&
props
List
.
Count
==
(
ctorParams
=
ctors
[
0
].
GetParameters
()).
Length
)
{
// check if reflection was kind enough to put everything in the right order for us
bool
ok
=
true
;
for
(
int
i
=
0
;
i
<
props
Arr
.
Length
;
i
++)
for
(
int
i
=
0
;
i
<
props
List
.
Count
;
i
++)
{
if
(!
string
.
Equals
(
props
Arr
[
i
].
Name
,
ctorParams
[
i
].
Name
,
StringComparison
.
OrdinalIgnoreCase
))
if
(!
string
.
Equals
(
props
List
[
i
].
Name
,
ctorParams
[
i
].
Name
,
StringComparison
.
OrdinalIgnoreCase
))
{
ok
=
false
;
break
;
...
...
@@ -2436,7 +2454,7 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
if
(
ok
)
{
// pre-sorted; the reflection gods have smiled upon us
props
=
props
Arr
;
props
=
props
List
;
}
else
{
// might still all be accounted for; check the hard way
var
positionByName
=
new
Dictionary
<
string
,
int
>(
StringComparer
.
OrdinalIgnoreCase
);
...
...
@@ -2444,13 +2462,13 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
{
positionByName
[
param
.
Name
]
=
param
.
Position
;
}
if
(
positionByName
.
Count
==
props
Arr
.
Length
)
if
(
positionByName
.
Count
==
props
List
.
Count
)
{
int
[]
positions
=
new
int
[
props
Arr
.
Length
];
int
[]
positions
=
new
int
[
props
List
.
Count
];
ok
=
true
;
for
(
int
i
=
0
;
i
<
props
Arr
.
Length
;
i
++)
for
(
int
i
=
0
;
i
<
props
List
.
Count
;
i
++)
{
if
(!
positionByName
.
TryGetValue
(
props
Arr
[
i
].
Name
,
out
int
pos
))
if
(!
positionByName
.
TryGetValue
(
props
List
[
i
].
Name
,
out
int
pos
))
{
ok
=
false
;
break
;
...
...
@@ -2459,13 +2477,17 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
}
if
(
ok
)
{
Array
.
Sort
(
positions
,
propsArr
);
props
=
propsArr
;
props
=
propsList
.
ToArray
(
);
Array
.
Sort
(
positions
,
(
PropertyInfo
[])
props
)
;
}
}
}
}
props
=
props
??
propsArr
.
OrderBy
(
x
=>
x
.
Name
);
if
(
props
==
null
)
{
propsList
.
Sort
(
new
PropertyInfoByNameComparer
());
props
=
propsList
;
}
if
(
filterParams
)
{
props
=
FilterParameters
(
props
,
identity
.
sql
);
...
...
@@ -2677,7 +2699,7 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
// stack is currently [parameters]
il
.
Emit
(
OpCodes
.
Pop
);
// stack is now empty
if
(
literals
.
Count
!=
0
&&
props
Arr
!=
null
)
if
(
literals
.
Count
!=
0
&&
props
List
!=
null
)
{
il
.
Emit
(
OpCodes
.
Ldarg_0
);
// command
il
.
Emit
(
OpCodes
.
Ldarg_0
);
// command, command
...
...
@@ -2690,12 +2712,12 @@ private static List<IMemberMap> GetValueTupleMembers(Type type, string[] names)
// find the best member, preferring case-sensitive
PropertyInfo
exact
=
null
,
fallback
=
null
;
string
huntName
=
literal
.
Member
;
for
(
int
i
=
0
;
i
<
props
Arr
.
Length
;
i
++)
for
(
int
i
=
0
;
i
<
props
List
.
Count
;
i
++)
{
string
thisName
=
props
Arr
[
i
].
Name
;
string
thisName
=
props
List
[
i
].
Name
;
if
(
string
.
Equals
(
thisName
,
huntName
,
StringComparison
.
OrdinalIgnoreCase
))
{
fallback
=
props
Arr
[
i
];
fallback
=
props
List
[
i
];
if
(
string
.
Equals
(
thisName
,
huntName
,
StringComparison
.
Ordinal
))
{
exact
=
fallback
;
...
...
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