Skip to content

Commit 947b582

Browse files
authored
fix #1993 - when matching properties, prefer non-normalized property name (#1997)
1 parent 5bb98eb commit 947b582

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

Dapper/DefaultTypeMap.cs

+18
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,24 @@ public SqlMapper.IMemberMap GetConstructorParameter(ConstructorInfo constructor,
206206
{
207207
// same again, minus underscore delta
208208
name = name?.Replace("_", "");
209+
210+
// match normalized column name vs actual property name
211+
foreach (var member in members)
212+
{
213+
if (string.Equals(name, selector(member), StringComparison.Ordinal))
214+
{
215+
return member;
216+
}
217+
}
218+
foreach (var member in members)
219+
{
220+
if (string.Equals(name, selector(member), StringComparison.OrdinalIgnoreCase))
221+
{
222+
return member;
223+
}
224+
}
225+
226+
// match normalized column name vs normalized property name
209227
foreach (var member in members)
210228
{
211229
if (string.Equals(name, selector(member)?.Replace("_", ""), StringComparison.Ordinal))

tests/Dapper.Tests/ConstructorTests.cs

+66-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using System.Data;
32
using System.Linq;
43
using Xunit;
54

@@ -241,6 +240,72 @@ public void CtorWithoutUnderscores()
241240
Assert.Equal("def", obj.LastName);
242241
}
243242

243+
[Fact]
244+
public void Issue1993_PreferPropertyOverField() // https://github.com/DapperLib/Dapper/issues/1993
245+
{
246+
var oldValue = DefaultTypeMap.MatchNamesWithUnderscores;
247+
try
248+
{
249+
DefaultTypeMap.MatchNamesWithUnderscores = true;
250+
251+
var map = new DefaultTypeMap(typeof(ShowIssue1993));
252+
var first = map.GetMember("field_first");
253+
Assert.NotNull(first);
254+
Assert.Null(first.Field);
255+
Assert.Equal(nameof(ShowIssue1993.FieldFirst), first.Property?.Name);
256+
257+
var last = map.GetMember("field_last");
258+
Assert.NotNull(last);
259+
Assert.Null(last.Field);
260+
Assert.Equal(nameof(ShowIssue1993.FieldLast), last.Property?.Name);
261+
}
262+
finally
263+
{
264+
DefaultTypeMap.MatchNamesWithUnderscores = oldValue;
265+
}
266+
}
267+
268+
[Fact]
269+
public void Issue1993_Query()
270+
{
271+
var oldValue = DefaultTypeMap.MatchNamesWithUnderscores;
272+
try
273+
{
274+
DefaultTypeMap.MatchNamesWithUnderscores = true;
275+
276+
var obj = connection.QueryFirst<ShowIssue1993>("select 'abc' as field_first, 'def' as field_last");
277+
Assert.Equal("abc", obj.FieldFirst);
278+
Assert.Equal("def", obj.FieldLast);
279+
280+
Assert.Equal("abc", obj.AltFieldFirst);
281+
Assert.Equal("def", obj.AltFieldLast);
282+
}
283+
finally
284+
{
285+
DefaultTypeMap.MatchNamesWithUnderscores = oldValue;
286+
}
287+
}
288+
289+
public class ShowIssue1993
290+
{
291+
private string _fieldFirst { get; set; } = null!; // not actually a field
292+
public string FieldFirst
293+
{
294+
get => _fieldFirst;
295+
set => _fieldFirst = AltFieldFirst = value;
296+
}
297+
298+
public string FieldLast
299+
{
300+
get => _fieldLast;
301+
set => _fieldLast = AltFieldLast = value;
302+
}
303+
private string _fieldLast { get; set; } = null!;// not actually a field
304+
305+
public string AltFieldFirst { get; set; } = null!;
306+
public string AltFieldLast { get; set; } = null!;
307+
}
308+
244309
class Type_ParamsWithUnderscores
245310
{
246311
public string FirstName { get; }

0 commit comments

Comments
 (0)