public static Tuple <List <Expression>, List <Expression> > ExtractKeyNodes(Expression expression, ParameterExpression thisParameter, ParameterExpression otherParameter) { var walker = new EntityMatchWalker(thisParameter, otherParameter); walker.Visit(expression); return(Tuple.Create(walker._thisKey, walker._otherKey)); }
private static void SetFieldByKeys <TParent, TChild>( PropertyAccessor <TParent, TChild> schema, IList <TParent> parentEntities, IList <TChild> childEntities) where TParent : class where TChild : class { var predicate = schema.AssociationDescriptor.GetPredicate(typeof(TParent), typeof(TChild)) as Expression <Func <TParent, TChild, bool> >; if (predicate == null) { predicate = (p, o) => true; } var keyTuple = EntityMatchWalker.ExtractKeyNodes(predicate, predicate.Parameters[0], predicate.Parameters[1]); var thisKeyExpressions = keyTuple.Item1; var otherKeyExpressions = keyTuple.Item2; var otherKeys = KeyExpressionsToKeyHolder(schema.AssociationDescriptor.OtherKey, otherKeyExpressions); var thisKeys = KeyExpressionsToKeyHolder(schema.AssociationDescriptor.ThisKey, thisKeyExpressions); if (otherKeys.Any() && thisKeys.Any()) { var hasher = _fkHashFuncs.GetOrAdd(new FKHashFuncKey { OtherType = typeof(TChild), OtherKeys = otherKeys.ToList(), ThisType = typeof(TParent), ThisKeys = thisKeys.ToList() }, k => new FKHashCodeFunc <TParent, TChild>(CreateGetHashCodeFunc <TParent>(thisKeys), CreateGetHashCodeFunc <TChild>(otherKeys), predicate.Compile())); var typeHasher = hasher as FKHashCodeFunc <TParent, TChild>; var childLookup = childEntities.ToLookup(typeHasher.OtherHashCodeFunc); MatchEntityLookup(schema, parentEntities, typeHasher.AssociationPredicate, childLookup, typeHasher.ThisHashCodeFunc); } else { MatchEntityList(schema, parentEntities, childEntities, predicate.Compile()); } }