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));
        }
Esempio n. 2
0
        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());
            }
        }