Ejemplo n.º 1
0
        /// <summary>
        /// Performs projection for a single row. Evaluates each projection argument against the specified
        /// row, returning a result with the specified type.
        /// </summary>
        /// <param name="node">Projection expression.</param>
        /// <param name="row">Row to project.</param>
        /// <param name="resultType">Type of the projected row.</param>
        /// <returns>Projected row.</returns>
        private PropagatorResult Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType)
        {
            EntityUtil.CheckArgumentNull(node, "node");

            Debug.Assert(null != node.Projection, "CQT validates DbProjectExpression.Projection property");

            DbNewInstanceExpression projection = node.Projection as DbNewInstanceExpression;

            if (null == projection)
            {
                throw EntityUtil.NotSupported(System.Data.Entity.Strings.Update_UnsupportedProjection(node.Projection.ExpressionKind));
            }

            // Initialize empty structure containing space for every element of the projection.
            PropagatorResult[] projectedValues = new PropagatorResult[projection.Arguments.Count];

            // Extract value from the input row for every projection argument requested.
            for (int ordinal = 0; ordinal < projectedValues.Length; ordinal++)
            {
                projectedValues[ordinal] = Evaluator.Evaluate(projection.Arguments[ordinal], row, this);
            }

            // Return a new row containing projected values.
            PropagatorResult projectedRow = PropagatorResult.CreateStructuralValue(projectedValues, (StructuralType)resultType.EdmType, false);

            return(projectedRow);
        }
Ejemplo n.º 2
0
            /// <summary>
            /// Given default values for children members, produces a new default expression for the requested (parent) member.
            /// </summary>
            /// <param name="node">Parent member</param>
            /// <returns>Default value for parent member</returns>
            internal PropagatorResult Visit(EdmMember node)
            {
                PropagatorResult result;
                TypeUsage        nodeType = Helper.GetModelTypeUsage(node);

                if (Helper.IsScalarType(nodeType.EdmType))
                {
                    GetPropagatorResultForPrimitiveType(Helper.AsPrimitive(nodeType.EdmType), out result);
                }
                else
                {
                    // Construct a new 'complex type' (really any structural type) member.
                    StructuralType        structuralType = (StructuralType)nodeType.EdmType;
                    IBaseList <EdmMember> members        = TypeHelpers.GetAllStructuralMembers(structuralType);

                    PropagatorResult[] args = new PropagatorResult[members.Count];
                    for (int ordinal = 0; ordinal < members.Count; ordinal++)
                    //                    foreach (EdmMember member in members)
                    {
                        args[ordinal] = Visit(members[ordinal]);
                    }

                    result = PropagatorResult.CreateStructuralValue(args, structuralType, false);
                }

                return(result);
            }
Ejemplo n.º 3
0
            /// <summary>
            /// Specialization of <see cref="CreatePlaceholder" /> for a relationship set extent.
            /// </summary>
            /// <param name="associationSet"></param>
            /// <returns></returns>
            private PropagatorResult CreateAssociationSetPlaceholder(AssociationSet associationSet)
            {
                Debug.Assert(null != associationSet, "Caller must verify parameters are not null");

                var endMetadata = associationSet.ElementType.AssociationEndMembers;

                PropagatorResult[] endReferenceValues = new PropagatorResult[endMetadata.Count];

                // Create a reference expression for each end in the relationship
                for (int endOrdinal = 0; endOrdinal < endMetadata.Count; endOrdinal++)
                {
                    var        end        = endMetadata[endOrdinal];
                    EntityType entityType = (EntityType)((RefType)end.TypeUsage.EdmType).ElementType;

                    // Retrieve key values for this end
                    PropagatorResult[] keyValues = new PropagatorResult[entityType.KeyMembers.Count];
                    for (int memberOrdinal = 0; memberOrdinal < entityType.KeyMembers.Count; memberOrdinal++)
                    {
                        EdmMember        keyMember = entityType.KeyMembers[memberOrdinal];
                        PropagatorResult keyValue  = CreateMemberPlaceholder(keyMember);
                        keyValues[memberOrdinal] = keyValue;
                    }

                    RowType          endType = entityType.GetKeyRowType(m_parent.MetadataWorkspace);
                    PropagatorResult refKeys = PropagatorResult.CreateStructuralValue(keyValues, endType, false);

                    endReferenceValues[endOrdinal] = refKeys;
                }

                PropagatorResult result = PropagatorResult.CreateStructuralValue(endReferenceValues, associationSet.ElementType, false);

                return(result);
            }
Ejemplo n.º 4
0
        // Note that this is called only for association ends. Entities have key values inline.
        private PropagatorResult CreateEntityKeyResult(IEntityStateEntry stateEntry, EntityKey entityKey)
        {
            // get metadata for key
            EntityType entityType = entityKey.GetEntitySet(m_translator.MetadataWorkspace).ElementType;
            RowType    keyRowType = entityType.GetKeyRowType(m_translator.MetadataWorkspace);

            ExtractorMetadata keyMetadata = m_translator.GetExtractorMetadata(stateEntry.EntitySet, keyRowType);
            int keyMemberCount            = keyRowType.Properties.Count;

            PropagatorResult[] keyValues = new PropagatorResult[keyMemberCount];

            for (int ordinal = 0; ordinal < keyRowType.Properties.Count; ordinal++)
            {
                EdmMember keyMember = keyRowType.Properties[ordinal];
                // retrieve information about this key value
                MemberInformation keyMemberInformation = keyMetadata.m_memberMap[ordinal];

                int keyIdentifier = m_translator.KeyManager.GetKeyIdentifierForMemberOffset(entityKey, ordinal, keyRowType.Properties.Count);

                object keyValue = null;
                if (entityKey.IsTemporary)
                {
                    // If the EntityKey is temporary, we need to retrieve the appropriate
                    // key value from the entity itself (or in this case, the IEntityStateEntry).
                    IEntityStateEntry entityEntry = stateEntry.StateManager.GetEntityStateEntry(entityKey);
                    Debug.Assert(entityEntry.State == EntityState.Added,
                                 "The corresponding entry for a temp EntityKey should be in the Added State.");
                    keyValue = entityEntry.CurrentValues[keyMember.Name];
                }
                else
                {
                    // Otherwise, we extract the value from within the EntityKey.
                    keyValue = entityKey.FindValueByName(keyMember.Name);
                }
                Debug.Assert(keyValue != null, "keyValue should've been retrieved.");

                // construct propagator result
                keyValues[ordinal] = PropagatorResult.CreateKeyValue(
                    keyMemberInformation.Flags,
                    keyValue,
                    stateEntry,
                    keyIdentifier);

                // see UpdateTranslator.Identifiers for information on key identifiers and ordinals
            }

            return(PropagatorResult.CreateStructuralValue(keyValues, keyMetadata.m_type, false));
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Converts a record to a propagator result
        /// </summary>
        /// <param name="stateEntry">state manager entry containing the record</param>
        /// <param name="isModified">Indicates whether the root element is modified (i.e., whether the type has changed)</param>
        /// <param name="record">Record to convert</param>
        /// <param name="useCurrentValues">Indicates whether we are retrieving current or original values.</param>
        /// <param name="translator">Translator for session context; registers new metadata for the record type if none
        /// exists</param>
        /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param>
        /// <returns>Result corresponding to the given record</returns>
        internal static PropagatorResult ExtractResultFromRecord(IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
                                                                 bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            StructuralType    structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            ExtractorMetadata metadata       = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            EntityKey         key            = stateEntry.EntityKey;

            PropagatorResult[] nestedValues = new PropagatorResult[record.FieldCount];
            for (int ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(stateEntry, record, useCurrentValues, key,
                                                                ordinal, modifiedPropertiesBehavior);
            }

            return(PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified));
        }
Ejemplo n.º 6
0
            /// <summary>
            /// Specialization of <see cref="CreatePlaceholder" /> for an entity set extent.
            /// </summary>
            /// <param name="entitySet"></param>
            /// <returns></returns>
            private PropagatorResult CreateEntitySetPlaceholder(EntitySet entitySet)
            {
                EntityUtil.CheckArgumentNull(entitySet, "entitySet");
                ReadOnlyMetadataCollection <EdmProperty> members = entitySet.ElementType.Properties;

                PropagatorResult[] memberValues = new PropagatorResult[members.Count];

                for (int ordinal = 0; ordinal < members.Count; ordinal++)
                {
                    PropagatorResult memberValue = CreateMemberPlaceholder(members[ordinal]);
                    memberValues[ordinal] = memberValue;
                }

                PropagatorResult result = PropagatorResult.CreateStructuralValue(memberValues, entitySet.ElementType, false);

                return(result);
            }
Ejemplo n.º 7
0
            /// <summary>
            /// Produce a tuple containing joined rows.
            /// </summary>
            /// <param name="left">Left row.</param>
            /// <param name="right">Right row.</param>
            /// <param name="leftKey">Key used to join left element.</param>
            /// <param name="rightKey">Key used to join right element.</param>
            /// <param name="result">Result change node; used for type information.</param>
            /// <returns>Result of joining the input rows.</returns>
            private PropagatorResult CreateResultTuple(Tuple <CompositeKey, PropagatorResult> left, Tuple <CompositeKey, PropagatorResult> right, ChangeNode result)
            {
                // using ref compare to avoid triggering value based
                CompositeKey leftKey  = left.Item1;
                CompositeKey rightKey = right.Item1;
                Dictionary <PropagatorResult, PropagatorResult> map = null;

                if (!object.ReferenceEquals(null, leftKey) &&
                    !object.ReferenceEquals(null, rightKey) &&
                    !object.ReferenceEquals(leftKey, rightKey))
                {
                    // Merge key values from the left and the right (since they're equal, there's a possibility we'll
                    // project values only from the left or the right hand side and lose important context.)
                    CompositeKey mergedKey = leftKey.Merge(m_parent.m_updateTranslator.KeyManager, rightKey);
                    // create a dictionary so that we can replace key values with merged key values (carrying context
                    // from both sides)
                    map = new Dictionary <PropagatorResult, PropagatorResult>();
                    for (int i = 0; i < leftKey.KeyComponents.Length; i++)
                    {
                        map[leftKey.KeyComponents[i]]  = mergedKey.KeyComponents[i];
                        map[rightKey.KeyComponents[i]] = mergedKey.KeyComponents[i];
                    }
                }

                PropagatorResult[] joinRecordValues = new PropagatorResult[2];
                joinRecordValues[0] = left.Item2;
                joinRecordValues[1] = right.Item2;
                PropagatorResult join = PropagatorResult.CreateStructuralValue(joinRecordValues, (StructuralType)result.ElementType.EdmType, false);

                // replace with merged key values as appropriate
                if (null != map)
                {
                    PropagatorResult replacement;
                    join = join.Replace(original => map.TryGetValue(original, out replacement) ? replacement : original);
                }

                return(join);
            }