I have two collections. Each collection contains instances of a specific type. I need to join these two collections using one of the properties of the instances from each of
The first clue to solving this is to re-write your join using lamda syntax for the Join
var query = fMyTranList.Join(fYourTranList,
a => a.MyAmountGBP,
b => b.YourAmountGBP,
(c,d) => new
{
MyId = c.Id,
YourId = d.Id,
MyAmtUSD = c.MyAmountUSD,
MyAmtGBP = c.MyAmountGBP,
YourAmtUSD = d.YourAmountUSD,
YourAmtGBP = d.YourAmountGBP
});
Live: http://rextester.com/OGC85986
Which should make it clear that making this dynamic would require passing in to your "generic" join function 3 functions
Func
function for selecting the key for LHSFunc
function for selecting the key for RHSFunc
function for selecting the resultSo from there you could use reflection to make this all a bit dynamic:
public static class DynamicJoinExtensions
{
public static IEnumerable DynamicJoin(this IEnumerable myTran, IEnumerable yourTran, params Tuple[] keys)
{
var outerKeySelector = CreateFunc(keys.Select(k => k.Item1).ToArray());
var innerKeySelector = CreateFunc(keys.Select(k => k.Item2).ToArray());
return myTran.Join(yourTran, outerKeySelector, innerKeySelector, (c, d) => new
{
MyId = c.Id,
YourId = d.Id,
MyAmtUSD = c.MyAmountUSD,
MyAmtGBP = c.MyAmountGBP,
YourAmtUSD = d.YourAmountUSD,
YourAmtGBP = d.YourAmountGBP
}, new ObjectArrayComparer());
}
private static Func CreateFunc(string[] keys)
{
var type = typeof(TObject);
return delegate(TObject o)
{
var data = new object[keys.Length];
for(var i = 0;i
{
public bool Equals(object[] x, object[] y)
{
return x.Length == y.Length
&& Enumerable.SequenceEqual(x, y);
}
public int GetHashCode(object[] o)
{
var result = o.Aggregate((a, b) => a.GetHashCode() ^ b.GetHashCode());
return result.GetHashCode();
}
}
}
Usage to match your example would then be:
var query = fMyTranList.DynamicJoin(fYourTranList,
Tuple.Create("MyAmountGBP", "YourAmountGBP"));
but as the keys are params
you can pass as many as you like:
var query = fMyTranList.DynamicJoin(fYourTranList,
Tuple.Create("MyAmountGBP", "YourAmountGBP"),
Tuple.Create("AnotherMyTranProperty", "AnotherYourTranProperty"));
Live example: http://rextester.com/AAB2452