diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index acc4d9a9..a2402f1c 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -232,36 +232,36 @@ namespace Dapper /// The Field we should split and read the second object from (default: id) /// Number of seconds before command execution timeout /// - public static IEnumerable Query(this IDbConnection cnn, string sql, Action map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); + return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); } - public static IEnumerable Query(this IDbConnection cnn, string sql, Action map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); + return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); } - public static IEnumerable Query(this IDbConnection cnn, string sql, Action map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); + return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); } - public static IEnumerable Query(this IDbConnection cnn, string sql, Action map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) { - return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); + return MultiMap(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout); } class DontMap {} - static IEnumerable MultiMap(this IDbConnection cnn, string sql, object map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) + static IEnumerable MultiMap(this IDbConnection cnn, string sql, object map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) { - var results = MultiMapImpl(cnn, sql, map, param, transaction, splitOn, commandTimeout); + var results = MultiMapImpl(cnn, sql, map, param, transaction, splitOn, commandTimeout); return buffered ? results.ToList() : results; } - static IEnumerable MultiMapImpl(this IDbConnection cnn, string sql, object map, object param = null, IDbTransaction transaction = null, string splitOn = "Id", int? commandTimeout = null) + static IEnumerable MultiMapImpl(this IDbConnection cnn, string sql, object map, object param = null, IDbTransaction transaction = null, string splitOn = "Id", int? commandTimeout = null) { - var identity = new Identity(sql, cnn, typeof(T), param == null ? null : param.GetType(), otherTypes: new[] { typeof(T), typeof(U), typeof(V), typeof(Z), typeof(X) }); + var identity = new Identity(sql, cnn, typeof(TFirst), param == null ? null : param.GetType(), otherTypes: new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth) }); var info = GetCacheInfo(param, identity); using (var cmd = SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout)) @@ -291,30 +291,30 @@ namespace Dapper var otherDeserializer = new List(); split = nextSplit(); - info.Deserializer = GetDeserializer(identity, reader, 0, split); + info.Deserializer = GetDeserializer(identity, reader, 0, split); - if (typeof(U) != typeof(DontMap)) + if (typeof(TSecond) != typeof(DontMap)) { var next = nextSplit(); - otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); + otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); split = next; } - if (typeof(V) != typeof(DontMap)) + if (typeof(TThird) != typeof(DontMap)) { var next = nextSplit(); - otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); + otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); split = next; } - if (typeof(Z) != typeof(DontMap)) + if (typeof(TFourth) != typeof(DontMap)) { var next = nextSplit(); - otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); + otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); split = next; } - if (typeof(X) != typeof(DontMap)) + if (typeof(TFifth) != typeof(DontMap)) { var next = nextSplit(); - otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); + otherDeserializer.Add(GetDeserializer(identity, reader, split, next - split, returnNullIfFirstMissing: true)); } info.OtherDeserializers = otherDeserializer.ToArray(); @@ -322,57 +322,37 @@ namespace Dapper queryCache[identity] = info; } - var deserializer = (Func)info.Deserializer; - var deserializer2 = (Func)info.OtherDeserializers[0]; + var deserializer = (Func)info.Deserializer; + var deserializer2 = (Func)info.OtherDeserializers[0]; - Func mapIt = null; + Func mapIt = null; if (info.OtherDeserializers.Length == 1) { - mapIt = r => - { - var tmp = deserializer(r); - ((Action)map)(tmp, deserializer2(r)); - return tmp; - }; + mapIt = r => ((Func)map)(deserializer(r), deserializer2(r)); } if (info.OtherDeserializers.Length > 1) { - var deserializer3 = (Func)info.OtherDeserializers[1]; + var deserializer3 = (Func)info.OtherDeserializers[1]; if (info.OtherDeserializers.Length == 2) { - mapIt = r => - { - var tmp = deserializer(r); - ((Action)map)(tmp, deserializer2(r), deserializer3(r)); - return tmp; - }; + mapIt = r => ((Func)map)(deserializer(r), deserializer2(r), deserializer3(r)); } if (info.OtherDeserializers.Length > 2) { - var deserializer4 = (Func)info.OtherDeserializers[2]; + var deserializer4 = (Func)info.OtherDeserializers[2]; if (info.OtherDeserializers.Length == 3) { - mapIt = r => - { - var tmp = deserializer(r); - ((Action)map)(tmp, deserializer2(r), deserializer3(r), deserializer4(r)); - return tmp; - }; + mapIt = r => ((Func)map)(deserializer(r), deserializer2(r), deserializer3(r),deserializer4(r)); } if (info.OtherDeserializers.Length > 3) { - var deserializer5 = (Func)info.OtherDeserializers[3]; - mapIt = r => - { - var tmp = deserializer(r); - ((Action)map)(tmp, deserializer2(r), deserializer3(r), deserializer4(r), deserializer5(r)); - return tmp; - }; + var deserializer5 = (Func)info.OtherDeserializers[3]; + mapIt = r => ((Func)map)(deserializer(r), deserializer2(r), deserializer3(r), deserializer4(r),deserializer5(r)); } } } @@ -386,7 +366,6 @@ namespace Dapper } } - private static CacheInfo GetCacheInfo(object param, Identity identity) { CacheInfo info; @@ -856,6 +835,4 @@ namespace Dapper } } } - - } diff --git a/Tests/PerformanceTests.cs b/Tests/PerformanceTests.cs index d054c764..e96adcf8 100644 --- a/Tests/PerformanceTests.cs +++ b/Tests/PerformanceTests.cs @@ -126,10 +126,10 @@ namespace SqlMapper petapocoFast.ForceDateTimesToUtc = false; tests.Add(id => petapocoFast.Fetch("SELECT * from Posts where Id=@0", id), "PetaPoco (Fast)"); - // Subsonic ActiveRecord + // Subsonic ActiveRecord tests.Add(id => SubSonic.Post.SingleOrDefault(x => x.Id == id), "SubSonic ActiveRecord.SingleOrDefault"); - // Subsonic ActiveRecord + // Subsonic coding horror SubSonic.tempdbDB db=new SubSonic.tempdbDB(); tests.Add(id => new SubSonic.Query.CodingHorror(db.Provider, "select * from Posts where Id = @0", id).ExecuteTypedList(), "SubSonic Coding Horror"); diff --git a/Tests/Tests.cs b/Tests/Tests.cs index 84d54aa5..49c1ad28 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -274,7 +274,7 @@ namespace SqlMapper left join #Users u on u.Id = p.OwnerId Order by p.Id"; - var data = connection.Query(sql, (post, user) => { post.Owner = user; }).ToList(); + var data = connection.Query(sql, (post, user) => { post.Owner = user; return post; }).ToList(); var p = data.First(); p.Content.IsEqualTo("Sams Post1"); @@ -308,7 +308,7 @@ Order by p.Id"; left join #Users u on u.Id = p.OwnerId Order by p.Id"; - var data = connection.Query(sql, (post, user) => { post.Owner = user; }).ToList(); + var data = connection.Query(sql, (post, user) => { post.Owner = user; return post; }).ToList(); var p = data.First(); // hairy extension method support for dynamics @@ -341,8 +341,8 @@ Order by p.Id"; public void TestMultiMappingVariations() { var sql = @"select 1 as Id, 'a' as Content, 2 as Id, 'b' as Content, 3 as Id, 'c' as Content, 4 as Id, 'd' as Content, 5 as Id, 'e' as Content"; - - var order = connection.Query(sql, (o, owner, creator) => { o.Owner = owner; o.Creator = creator; }).First(); + + var order = connection.Query(sql, (o, owner, creator) => { o.Owner = owner; o.Creator = creator; return o; }).First(); Assert.IsEqualTo(order.Id, 1); Assert.IsEqualTo(order.Content, "a"); @@ -351,11 +351,12 @@ Order by p.Id"; Assert.IsEqualTo(order.Creator.Id, 3); Assert.IsEqualTo(order.Creator.Content, "c"); - order = connection.Query(sql, (o, owner, creator, address) => + order = connection.Query(sql, (o, owner, creator, address) => { o.Owner = owner; o.Creator = creator; o.Owner.Address = address; + return o; }).First(); Assert.IsEqualTo(order.Id, 1); @@ -367,7 +368,7 @@ Order by p.Id"; Assert.IsEqualTo(order.Owner.Address.Id, 4); Assert.IsEqualTo(order.Owner.Address.Content, "d"); - order = connection.Query(sql, (a, b, c, d, e) => { a.B = b; a.C = c; a.C.D = d; a.E = e; }).First(); + order = connection.Query(sql, (a, b, c, d, e) => { a.B = b; a.C = c; a.C.D = d; a.E = e; return a; }).First(); Assert.IsEqualTo(order.Id, 1); Assert.IsEqualTo(order.Content, "a"); @@ -440,7 +441,7 @@ Order by p.Id"; cnn.Execute("insert Posts values(2,'title2','body2',null)"); cnn.Execute("insert Authors values(1,'sam')"); - var data = cnn.Query(@"select * from Posts p left join Authors a on a.ID = p.AuthorID", (post, author) => { post.Author = author; }).ToList(); + var data = cnn.Query(@"select * from Posts p left join Authors a on a.ID = p.AuthorID", (post, author) => { post.Author = author; return post; }).ToList(); var firstPost = data.First(); firstPost.Title.IsEqualTo("title"); firstPost.Author.Name.IsEqualTo("sam");