Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #253, use user defined TypeHandlers over internal implementations. #258

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Dapper NET40/SqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -885,15 +885,16 @@ internal static DbType LookupDbType(Type type, string name, bool demand, out ITy
{
return DbType.Binary;
}
if (typeHandlers.TryGetValue(type, out handler))
{
return DbType.Object;
}
if (typeof(IEnumerable).IsAssignableFrom(type))
{
return DynamicParameters.EnumerableMultiParameter;
}

if (typeHandlers.TryGetValue(type, out handler))
{
return DbType.Object;
}

switch (type.FullName)
{
case "Microsoft.SqlServer.Types.SqlGeography":
Expand Down
133 changes: 96 additions & 37 deletions Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1571,10 +1571,10 @@ public void TestMultiMappingWithNonReturnedProperty()
2 as BlogId, 'Blog' as Title";
var postWithBlog = connection.Query<Post_DupeProp, Blog_DupeProp, Post_DupeProp>(sql,
(p, b) =>
{
p.Blog = b;
return p;
}, splitOn: "BlogId").First();
{
p.Blog = b;
return p;
}, splitOn: "BlogId").First();

postWithBlog.PostId.IsEqualTo(1);
postWithBlog.Title.IsEqualTo("Title");
Expand Down Expand Up @@ -1830,15 +1830,15 @@ public void ParentChildIdentityAssociations()
var lookup = new Dictionary<int, Parent>();
var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5",
(parent, child) =>
{
Parent found;
if (!lookup.TryGetValue(parent.Id, out found))
{
lookup.Add(parent.Id, found = parent);
}
found.Children.Add(child);
return found;
}).Distinct().ToDictionary(p => p.Id);
Parent found;
if (!lookup.TryGetValue(parent.Id, out found))
{
lookup.Add(parent.Id, found = parent);
}
found.Children.Add(child);
return found;
}).Distinct().ToDictionary(p => p.Id);
parents.Count().IsEqualTo(3);
parents[1].Children.Select(c => c.Id).SequenceEqual(new[] { 1, 2, 4 }).IsTrue();
parents[2].Children.Select(c => c.Id).SequenceEqual(new[] { 3 }).IsTrue();
Expand Down Expand Up @@ -2782,9 +2782,9 @@ public void TestIssue131()
var results = connection.Query<dynamic, int, dynamic>(
"SELECT 1 Id, 'Mr' Title, 'John' Surname, 4 AddressCount",
(person, addressCount) =>
{
return person;
},
{
return person;
},
splitOn: "AddressCount"
).FirstOrDefault();

Expand Down Expand Up @@ -3175,9 +3175,12 @@ class HasDoubleDecimal

public void DataTableParameters()
{
try { connection.Execute("drop proc #DataTableParameters"); } catch { }
try { connection.Execute("drop table #DataTableParameters"); } catch { }
try { connection.Execute("drop type MyTVPType"); } catch { }
try { connection.Execute("drop proc #DataTableParameters"); }
catch { }
try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids");

Expand All @@ -3193,20 +3196,23 @@ public void DataTableParameters()
{
connection.Query<int>("select count(1) from @ids", new { ids = table.AsTableValuedParameter() }).First();
throw new InvalidOperationException();
} catch (Exception ex)
}
catch (Exception ex)
{
ex.Message.Equals("The table type parameter 'ids' must have a valid type name.");
}
}
public void SO26468710_InWithTVPs()
{
// this is just to make it re-runnable; normally you only do this once
try { connection.Execute("drop type MyIdList"); } catch { }
try { connection.Execute("drop type MyIdList"); }
catch { }
connection.Execute("create type MyIdList as table(id int);");

DataTable ids = new DataTable {
Columns = {{"id", typeof(int)}},
Rows = {{1},{3},{5}}
DataTable ids = new DataTable
{
Columns = { { "id", typeof(int) } },
Rows = { { 1 }, { 3 }, { 5 } }
};
ids.SetTypeName("MyIdList");
int sum = connection.Query<int>(@"
Expand All @@ -3217,9 +3223,12 @@ public void SO26468710_InWithTVPs()
}
public void DataTableParametersWithExtendedProperty()
{
try { connection.Execute("drop proc #DataTableParameters"); } catch { }
try { connection.Execute("drop table #DataTableParameters"); } catch { }
try { connection.Execute("drop type MyTVPType"); } catch { }
try { connection.Execute("drop proc #DataTableParameters"); }
catch { }
try { connection.Execute("drop table #DataTableParameters"); }
catch { }
try { connection.Execute("drop type MyTVPType"); }
catch { }
connection.Execute("create type MyTVPType as table (id int)");
connection.Execute("create proc #DataTableParameters @ids MyTVPType readonly as select count(1) from @ids");

Expand Down Expand Up @@ -3504,6 +3513,50 @@ public void SO24740733_TestCustomValueSingleColumn()

foo.Value.IsEqualTo(200);
}
public class StringListTypeHandler : Dapper.SqlMapper.TypeHandler<List<String>>
{
private StringListTypeHandler() { }
public static readonly StringListTypeHandler Default = new StringListTypeHandler();
//Just a simple List<string> type handler implementation
public override void SetValue(IDbDataParameter parameter, List<string> value)
{
parameter.Value = String.Join(",", value);
}

public override List<string> Parse(object value)
{
return ((value as String) ?? "").Split(',').ToList();
}
}
public class MyObjectWithStringList
{
public List<String> Names { get; set; }
}
public void Issue253_TestIEnumerableTypeHandlerParsing()
{
Dapper.SqlMapper.ResetTypeHandlers();
Dapper.SqlMapper.AddTypeHandler(StringListTypeHandler.Default);
var foo = connection.Query<MyObjectWithStringList>("SELECT 'Sam,Kyro' AS Names").Single();
foo.Names.IsSequenceEqualTo(new[] { "Sam", "Kyro" });
}
public void Issue253_TestIEnumerableTypeHandlerSetParameterValue()
{
Dapper.SqlMapper.ResetTypeHandlers();
Dapper.SqlMapper.AddTypeHandler(StringListTypeHandler.Default);

connection.Execute("CREATE TABLE #Issue253 (Names VARCHAR(50) NOT NULL);");
try
{
String names = "Sam,Kyro";
List<String> names_list = names.Split(',').ToList();
var foo = connection.Query<String>("INSERT INTO #Issue253 (Names) VALUES (@Names); SELECT Names FROM #Issue253;", new { Names = names_list }).Single();
foo.IsEqualTo(names);
}
finally
{
connection.Execute("DROP TABLE #Issue253;");
}
}

public void Issue130_IConvertible()
{
Expand Down Expand Up @@ -3624,7 +3677,8 @@ public class LocalDateResult
public LocalDate? NullableIsNull { get; set; }
}

public class LotsOfNumerics {
public class LotsOfNumerics
{
public enum E_Byte : byte { A = 0, B = 1 }
public enum E_SByte : sbyte { A = 0, B = 1 }
public enum E_Short : short { A = 0, B = 1 }
Expand Down Expand Up @@ -3832,7 +3886,8 @@ public void SO25069578_DynamicParams_Procs()
var parameters = new DynamicParameters();
parameters.Add("foo", "bar");
// parameters = new DynamicParameters(parameters);
try { connection.Execute("drop proc SO25069578"); } catch { }
try { connection.Execute("drop proc SO25069578"); }
catch { }
connection.Execute("create proc SO25069578 @foo nvarchar(max) as select @foo as [X]");
var tran = connection.BeginTransaction(); // gist used transaction; behaves the same either way, though
var row = connection.Query<HazX>("SO25069578", parameters,
Expand All @@ -3849,14 +3904,15 @@ public void Issue149_TypeMismatch_SequentialAccess()
{
var result = connection.Query<Issue149_Person>(@"select @guid as Id", new { guid }).First();
error = null;
} catch(Exception ex)
}
catch (Exception ex)
{
error = ex.Message;
}
error.IsEqualTo("Error parsing column 0 (Id=cf0ef7ac-b6fe-4e24-aeda-a2b45bb5654e - Object)");
}
public class Issue149_Person { public string Id { get; set; } }

public class HazX
{
public string X { get; set; }
Expand All @@ -3878,7 +3934,7 @@ public void SO25297173_DynamicIn()
var queryParams = new Dictionary<string, object> {
{ "myIds", new [] { 5, 6 } }
};

var dynamicParams = new DynamicParameters(queryParams);
List<int> result = connection.Query<int>(query, dynamicParams).ToList();
result.Count.IsEqualTo(2);
Expand All @@ -3900,8 +3956,10 @@ public void AllowIDictionaryParameters()
public void Issue178_SqlServer()
{
const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); } catch { }
try { connection.Execute("create table Issue178(id int not null)"); } catch { }
try { connection.Execute("drop table Issue178"); }
catch { }
try { connection.Execute("create table Issue178(id int not null)"); }
catch { }
// raw ADO.net
var sqlCmd = new SqlCommand(sql, connection);
using (IDataReader reader1 = sqlCmd.ExecuteReader())
Expand Down Expand Up @@ -3930,7 +3988,8 @@ public void Issue178_SqlServer()
{
connection.Open();
const string sql = @"select count(*) from Issue178";
try { connection.Execute("drop table Issue178"); } catch { }
try { connection.Execute("drop table Issue178"); }
catch { }
connection.Execute("create table Issue178(id int not null)");
connection.Execute("insert into Issue178(id) values(42)");
// raw ADO.net
Expand Down Expand Up @@ -4055,7 +4114,7 @@ public class Dyno
public dynamic Id { get; set; }
public string Name { get; set; }

public object Foo { get;set; }
public object Foo { get; set; }
}

public void Issue151_ExpandoObjectArgsQuery()
Expand Down Expand Up @@ -4147,8 +4206,8 @@ Field INT NOT NULL PRIMARY KEY IDENTITY(1,1),
public void Issue220_InParameterCanBeSpecifiedInAnyCase()
{
// note this might fail if your database server is case-sensitive
connection.Query<int>("select * from (select 1 as Id) as X where Id in @ids", new {Ids = new[] {1}})
.IsSequenceEqualTo(new[] {1});
connection.Query<int>("select * from (select 1 as Id) as X where Id in @ids", new { Ids = new[] { 1 } })
.IsSequenceEqualTo(new[] { 1 });
}

#if POSTGRESQL
Expand Down