Esempio n. 1
0
            private List <EntityShaperExpression> GetNestedShapers(IEntityType entityType, Expression valueBufferExpression)
            {
                var nestedEntities = new List <EntityShaperExpression>();

                foreach (var ownedNavigation in entityType.GetNavigations().Concat(entityType.GetDerivedNavigations()))
                {
                    var fk = ownedNavigation.ForeignKey;
                    if (!fk.IsOwnership ||
                        ownedNavigation.IsDependentToPrincipal() ||
                        fk.DeclaringEntityType.IsDocumentRoot())
                    {
                        continue;
                    }

                    var targetType = ownedNavigation.GetTargetType();

                    var nestedValueBufferExpression = _shapedQueryCompilingExpressionVisitor.CreateReadValueExpression(
                        valueBufferExpression,
                        valueBufferExpression.Type,
                        ownedNavigation.GetIndex(),
                        ownedNavigation);

                    var nestedShaper = new EntityShaperExpression(
                        targetType, nestedValueBufferExpression, nullable: true, ownedNavigation,
                        GetNestedShapers(targetType, nestedValueBufferExpression));
                    nestedEntities.Add(nestedShaper);
                }

                return(nestedEntities.Count == 0 ? null : nestedEntities);
            }
            private Expression InjectEmbeddedMaterializers(Expression materializerExpression, Expression valueBufferExpression)
            {
                if (_currentEmbeddedNavigationInfo == null ||
                    _currentEmbeddedNavigationInfo.EmbeddedNavigations.Count <= 0 ||
                    !(materializerExpression is BlockExpression blockExpression))
                {
                    return(materializerExpression);
                }

                var expressions      = new List <Expression>(blockExpression.Expressions);
                var instanceVariable = expressions[expressions.Count - 1];

                expressions.RemoveAt(expressions.Count - 1);

                var concreteEntityTypeVariableName = "entityType" + _currentEntityIndex;
                var concreteEntityTypeVariable     = blockExpression.Variables.Single(v => v.Name == concreteEntityTypeVariableName);

                var embeddedExpressions          = new List <Expression>(blockExpression.Expressions);
                var parentEmbeddedNavigationInfo = _currentEmbeddedNavigationInfo;

                foreach (var embeddedNavigation in parentEmbeddedNavigationInfo.EmbeddedNavigations)
                {
                    var navigation = embeddedNavigation.Navigation;
                    var embeddedValueBufferExpression = _shapedQueryCompilingExpressionVisitor.CreateReadValueExpression(
                        valueBufferExpression,
                        valueBufferExpression.Type,
                        navigation.GetIndex(),
                        navigation);

                    _currentEmbeddedNavigationInfo = embeddedNavigation;
                    var embeddedShaper = Visit(
                        new EntityShaperExpression(navigation.GetTargetType(), embeddedValueBufferExpression, nullable: true));

                    var navigationMemberInfo      = navigation.GetMemberInfo(forConstruction: true, forSet: true);
                    var convertedInstanceVariable = navigationMemberInfo.DeclaringType.IsAssignableFrom(instanceVariable.Type)
                        ? instanceVariable
                        : Expression.Convert(instanceVariable, navigationMemberInfo.DeclaringType);

                    Expression navigationExpression;
                    if (navigation.IsCollection())
                    {
                        var accessorExpression = Expression.Constant(new ClrCollectionAccessorFactory().Create(navigation));
                        navigationExpression = Expression.Call(accessorExpression, _accessorAddRangeMethodInfo,
                                                               convertedInstanceVariable, new CollectionShaperExpression(null, embeddedShaper, navigation, null));
                        throw new NotImplementedException();
                    }
                    else
                    {
                        navigationExpression = Expression.Assign(Expression.MakeMemberAccess(
                                                                     convertedInstanceVariable,
                                                                     navigationMemberInfo),
                                                                 embeddedShaper);
                    }

                    var embeddedMaterializer = Expression.IfThen(
                        Expression.Call(_isAssignableFromMethodInfo,
                                        Expression.Constant(navigation.DeclaringEntityType),
                                        concreteEntityTypeVariable),
                        navigationExpression);

                    embeddedExpressions.Add(embeddedMaterializer);
                }
                _currentEmbeddedNavigationInfo = parentEmbeddedNavigationInfo;

                expressions.Add(Expression.IfThen(
                                    Expression.NotEqual(instanceVariable, Expression.Constant(null, instanceVariable.Type)),
                                    Expression.Block(embeddedExpressions)));
                expressions.Add(instanceVariable);
                return(blockExpression.Update(blockExpression.Variables, expressions));
            }