-
-
Save SamSaffron/1225723 to your computer and use it in GitHub Desktop.
cnn.QueryMultiple<Table<Order>,Table<OrderLine>,Order>( | |
@"select * from Orders | |
select * from OrderLine", (orders, lines) => | |
{ | |
var map = lines.ToDictionary(line => line.OrderId); | |
foreach(var order in orders) | |
{ | |
order.Lines = map[o.Id]; | |
yield return order; | |
} | |
}); | |
// another option, infer Table for single: | |
cnn.QueryMultiple<Table<Order,User>,OrderLine,Order>( | |
@"select * from Orders | |
left join Users u on u.Id = OwnerId | |
select * from OrderLine", (orders, lines) => | |
{ | |
var map = lines.ToDictionary(line => line.OrderId); | |
foreach(var order in orders.Map((o,u) => {o.Owner = u; return o;})) | |
{ | |
order.Lines = map[o.Id]; | |
yield return order; | |
} | |
}); | |
// Same code today | |
grid = cnn.QueryMultiple( | |
@"select * from Orders | |
left join Users u on u.Id = OwnerId | |
select * from OrderLine"); | |
var orders = grid.Read<Order,User,Order>((o,u) => {o.Owner = u; return o;}).ToList(); | |
var map = grid.Read<OrderLine>().ToDictionary(line => line.OrderId); | |
foreach(var order in orders) | |
{ | |
order.Lines = map[order.Id]; | |
} |
It does not exist, but I assume I would make it an IEnumerable where T is something.
I went back and pulled up my existing code and compared it to this and my brain locked onto what you were asking and my jaw dropped. I'm not entirely sure I would appreciate this addition to the code, as I use it fairly differently. Here's one of my random methods, slightly anonymized:
public static RecordDTO SprocName(string param1, string param2) {
List<ThingIds> Things; /* the field returned is called ItemID */
List<UnitSet> UnitSet;
List<TemperatureData> Temps;
List<UnitIntervals> UnitIntervals;
using ( var con = DataAccessMaster.GetOpenConnection() ) {
using ( var multi = con.QueryMultiple( "SprocName", new { Param1 = param1, Param2 = param2} ) ) {
Things = multi.Read<ThingIds>().ToList();
UnitSet = multi.Read<UnitSet>( ).ToList( );
Temps = multi.Read<TemperatureData>( ).ToList( );
UnitIntervals = multi.Read<UnitIntervals>( ).ToList( );
}
}
return new RecordDTO {
Things = Things,
UnitSet = UnitSet,
Temps = Temps,
UnitIntervals = UnitIntervals
};
}
Isn't there a bug in the second option? Shouldn't it return o instead of u?
// another option, infer Table for single:
cnn.QueryMultiple<Table<Order,User>,OrderLine,Order>(
@"select * from Orders
left join Users u on u.Id = OwnerId
select * from OrderLine", (orders, lines) =>
{
var map = lines.ToDictionary(line => line.OrderId);
foreach(var order in orders.Map((o,u) => {o.Owner = u; return o;}))
{
order.Lines = map[o.Id];
yield return order;
}
});
If so that applies to the third example line as well
@william true ... changed it
@SamSaffron: .ToDictionary probably isn't right in any of the examples (why would we need multimap at all? :))
Can we get rid of even more boilerplate? For the multimap, I'd think all you really need to specify are the key selectors and the way to combine the results...
var results = cnn.Query<User, Order, OrderLine>
("select * from Users;select * from Order;select * from OrderLine")
.Map((user, order) => { order.User = user; return order; })
.MultiMap(order => order.Id,
line => line.OrderId,
(order, orderLines) => order.OrderLines = orderLines.ToList());
@JasonPunyon isn't he trying to avoid chaining in his revision?
@jcolebrand: He hasn't told me so I wouldn't know. I just followed a tweet here :)
@JasonPunyon me too! ;)
What is this "Table" magic you refer to? I feel lost now.