Skip to content
Open
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
3 changes: 2 additions & 1 deletion Dapper/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#nullable enable
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.get -> bool
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.set -> void
static Dapper.SqlMapper.Settings.PreferTypeHandlersForEnums.set -> void
static Dapper.SqlMapper.Query<TReturn>(this System.Data.IDbConnection! cnn, Dapper.CommandDefinition command, System.Type![]! types, System.Func<object![]!, TReturn>! map, string! splitOn = "Id") -> System.Collections.Generic.IEnumerable<TReturn>!
18 changes: 17 additions & 1 deletion Dapper/SqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,6 @@ private static IEnumerable<T> QueryImpl<T>(this IDbConnection cnn, CommandDefini
}

var func = tuple.Func;
var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType;
while (reader.Read())
{
object? val = func(reader);
Expand Down Expand Up @@ -1549,6 +1548,23 @@ public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFift
public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, object? param = null, IDbTransaction? transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) =>
MultiMap<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType);

/// <summary>
/// Perform a multi-mapping query with an arbitrary number of input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="cnn">The connection to query on.</param>
/// <param name="command">The command used to execute the query.</param>
/// <param name="types">Array of types in the recordset.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, CommandDefinition command, Type[] types, Func<object[], TReturn> map, string splitOn = "Id")
{
var results = MultiMapImpl(cnn, command, types, map, splitOn, null, null, true);
return command.Buffered ? results.ToList() : results;
}

/// <summary>
/// Perform a multi-mapping query with an arbitrary number of input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
Expand Down
46 changes: 46 additions & 0 deletions tests/Dapper.Tests/MultiMapTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,52 @@ public void TestMultiMapArbitraryMaps()
}
}

[Fact]
public void TestMultiMapArbitraryMapsCommandDefinition()
{
const string createSql = @"
create table #ReviewBoards (Id int, Name varchar(20), User1Id int, User2Id int, User3Id int, User4Id int, User5Id int, User6Id int, User7Id int, User8Id int, User9Id int)
create table #Users (Id int, Name varchar(20))

insert #Users values(9, 'User 9')
insert #ReviewBoards values(1, 'Review Board 1', 9, 9, 9, 9, 9, 9, 9, 9, 9)
";
connection.Execute(createSql);
try
{
const string sql = @"
select rb.Id, rb.Name, u1.*, u2.*, u3.*, u4.*, u5.*, u6.*, u7.*, u8.*, u9.*
from #ReviewBoards rb
inner join #Users u1 on u1.Id = rb.User1Id
inner join #Users u2 on u2.Id = rb.User2Id
inner join #Users u3 on u3.Id = rb.User3Id
inner join #Users u4 on u4.Id = rb.User4Id
inner join #Users u5 on u5.Id = rb.User5Id
inner join #Users u6 on u6.Id = rb.User6Id
inner join #Users u7 on u7.Id = rb.User7Id
inner join #Users u8 on u8.Id = rb.User8Id
inner join #Users u9 on u9.Id = rb.User9Id";

var types = new[] { typeof(ReviewBoard), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User), typeof(User) };
Func<object[], ReviewBoard> mapper = objects =>
{
var board = (ReviewBoard)objects[0];
board.User9 = (User)objects[9];
return board;
};

var command = new CommandDefinition(sql);
var data = connection.Query<ReviewBoard>(command, types, mapper).ToList();

Assert.Equal(1, data.Count);
Assert.Equal("User 9", data[0].User9!.Name);
}
finally
{
connection.Execute("drop table #Users drop table #ReviewBoards");
}
}

[Fact]
public void TestMultiMapGridReader()
{
Expand Down