コード例 #1
0
            protected virtual Expression VisitExtendedMemberInit(ExtendedMemberInitExpression node)
            {
                var newExpression = VisitAndConvert(node.NewExpression, nameof(VisitExtendedMemberInit));
                var arguments     = Visit(node.Arguments).ToArray();

                var entityType = model.FindEntityType(node.Type);

                if (entityType != null)
                {
                    var collectionMembers
                        = from n in entityType.GetNavigations()
                          where n.IsCollection()
                          from m in new[] { n.GetReadableMemberInfo(), n.GetWritableMemberInfo() }
                    select m;

                    for (var i = 0; i < arguments.Length; i++)
                    {
                        if (collectionMembers.Contains(node.WritableMembers[i]))
                        {
                            var sequenceType = node.WritableMembers[i].GetMemberType().GetSequenceType();

                            arguments[i]
                                = Expression.Coalesce(
                                      arguments[i].AsCollectionType(),
                                      Expression.New(typeof(List <>).MakeGenericType(sequenceType)));
                        }
                    }
                }

                return(node.Update(newExpression, arguments));
            }
コード例 #2
0
        private static bool FindExpressionForMember(ExtendedMemberInitExpression extendedMemberInitExpression, MemberInfo memberInfo, out Expression expression)
        {
            for (var i = 0; i < extendedMemberInitExpression.ReadableMembers.Count; i++)
            {
                var member = extendedMemberInitExpression.ReadableMembers[i];

                if (member.DeclaringType == memberInfo.DeclaringType &&
                    member.Name == memberInfo.Name)
                {
                    expression = extendedMemberInitExpression.Arguments[i];

                    return(true);
                }
            }

            return(FindExpressionForMember(extendedMemberInitExpression.NewExpression, memberInfo, out expression));
        }
コード例 #3
0
            protected virtual Expression VisitExtendedMemberInit(ExtendedMemberInitExpression node)
            {
                var newExpression = VisitAndConvert(node.NewExpression, nameof(VisitExtendedMemberInit));

                if (Finished)
                {
                    return(node.Update(newExpression, node.Arguments));
                }

                var arguments       = node.Arguments.ToList();
                var readableMembers = node.ReadableMembers.ToList();
                var writableMembers = node.WritableMembers.ToList();

                var currentMember     = path.Pop();
                var currentMemberInfo = currentMember.GetReadableMemberInfo();
                var foundMember       = false;

                for (var i = 0; i < arguments.Count; i++)
                {
                    var argument = arguments[i];

                    if (node.ReadableMembers[i] == currentMemberInfo)
                    {
                        foundMember = true;

                        if (path.Count == 0)
                        {
                            arguments[i] = includedExpression;
                            Finished     = true;
                        }
                        else
                        {
                            arguments[i] = Visit(argument);
                        }

                        break;
                    }
                }

                path.Push(currentMember);

                if (!foundMember && currentMemberInfo.DeclaringType.IsAssignableFrom(node.Type))
                {
                    Finished = true;

                    var writableMemberInfo = currentMember.GetWritableMemberInfo();

                    arguments.Add(
                        writableMemberInfo.GetMemberType().IsCollectionType()
                            ? includedExpression.AsCollectionType()
                            : includedExpression);

                    readableMembers.Add(currentMember.GetReadableMemberInfo());
                    writableMembers.Add(writableMemberInfo);

                    return(new ExtendedMemberInitExpression(
                               node.Type,
                               node.NewExpression,
                               arguments,
                               readableMembers,
                               writableMembers));
                }
                else
                {
                    return(node.Update(newExpression, arguments));
                }
            }
コード例 #4
0
        private Expression CreateMaterializationExpression(IEntityType type, BaseTableExpression table, Func <IProperty, Expression> makeColumnExpression)
        {
            var properties
                = (from p in type.GetProperties()
                   where !p.IsShadowProperty
                   select p).ToList();

            var navigations
                = (from n in type.GetNavigations()
                   where n.ForeignKey.IsOwnership && !n.IsDependentToPrincipal()
                   select n).ToList();

            var services
                = (from s in type.GetServiceProperties()
                   select s).ToList();

            var newExpression = CreateNewExpression(type, table, makeColumnExpression);

            properties.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo()));
            navigations.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo()));
            services.RemoveAll(p => newExpression.WritableMembers.Contains(p.GetWritableMemberInfo()));

            var arguments       = new Expression[properties.Count + navigations.Count + services.Count];
            var readableMembers = new MemberInfo[arguments.Length];
            var writableMembers = new MemberInfo[arguments.Length];

            var c = properties.Count;
            var d = 0;

            for (var i = 0; i < c; i++)
            {
                var property = properties[i - d];

                arguments[i]       = makeColumnExpression(property);
                readableMembers[i] = property.GetReadableMemberInfo();
                writableMembers[i] = property.GetWritableMemberInfo();
            }

            c += navigations.Count;
            d += properties.Count;

            for (var i = d; i < c; i++)
            {
                var navigation = navigations[i - d];

                arguments[i]       = CreateMaterializationExpression(navigation.GetTargetType(), table, makeColumnExpression);
                readableMembers[i] = navigation.GetReadableMemberInfo();
                writableMembers[i] = navigation.GetWritableMemberInfo();
            }

            c += services.Count;
            d += navigations.Count;

            for (var i = d; i < c; i++)
            {
                var service = services[i - d];

                arguments[i]       = GetBindingExpression(type, service.GetParameterBinding(), makeColumnExpression);
                readableMembers[i] = service.GetReadableMemberInfo();
                writableMembers[i] = service.GetWritableMemberInfo();
            }

            var materializer
                = new ExtendedMemberInitExpression(
                      type.ClrType,
                      newExpression,
                      arguments,
                      readableMembers,
                      writableMembers);

            var keySelector
                = CreateMaterializationKeySelector(type);

            if (keySelector != null)
            {
                var shadowProperties
                    = from p in type.GetProperties()
                      where p.IsShadowProperty
                      select(property : p, expression : makeColumnExpression(p));

                return(new EntityMaterializationExpression(
                           type,
                           IdentityMapMode.IdentityMap,
                           keySelector,
                           shadowProperties.Select(s => s.property),
                           shadowProperties.Select(s => s.expression),
                           materializer));
            }

            return(materializer);
        }