/// <summary>
 ///     DiscriminatedNewInstanceOp
 /// </summary>
 /// <param name="op"> the DiscriminatedNewInstanceOp </param>
 /// <param name="n"> corresponding node </param>
 /// <returns> new subtree </returns>
 public override Node Visit(DiscriminatedNewEntityOp op, Node n)
 {
     return FlattenConstructor(op, n);
 }
        /// <summary>
        ///     Given an explicit discriminator value, map to normalized values. Essentially, this allows
        ///     a discriminated new instance to coexist with free-floating entities, MEST, etc. which use
        ///     general purpose ordpath type ids (e.g. '0X0X')
        ///     An example of the normalization is given:
        ///     CASE
        ///     WHEN discriminator = 'Base' THEN '0X'
        ///     WHEN discriminator = 'Derived1' THEN '0X0X'
        ///     WHEN discriminator = 'Derived2' THEN '0X1X'
        ///     ELSE '0X2X' -- default case for 'Derived3'
        /// </summary>
        private Node NormalizeTypeDiscriminatorValues(DiscriminatedNewEntityOp op, Node discriminator)
        {
            var typeInfo = m_typeInfo.GetTypeInfo(op.Type);

            var normalizer = m_command.CreateCaseOp(typeInfo.RootType.TypeIdProperty.TypeUsage);
            var children = new List<Node>(op.DiscriminatorMap.TypeMap.Count * 2 - 1);
            for (var i = 0; i < op.DiscriminatorMap.TypeMap.Count; i++)
            {
                var discriminatorValue = op.DiscriminatorMap.TypeMap[i].Key;
                var type = op.DiscriminatorMap.TypeMap[i].Value;
                var currentTypeInfo = m_typeInfo.GetTypeInfo(md.TypeUsage.Create(type));

                var normalizedDiscriminatorConstant = CreateTypeIdConstant(currentTypeInfo);
                // for the last type, return the 'then' value
                if (i == op.DiscriminatorMap.TypeMap.Count - 1)
                {
                    // ELSE normalizedDiscriminatorValue
                    children.Add(normalizedDiscriminatorConstant);
                }
                else
                {
                    // WHEN discriminator = discriminatorValue THEN normalizedDiscriminatorValue
                    var discriminatorValueOp =
                        m_command.CreateConstantOp(
                            md.Helper.GetModelTypeUsage(op.DiscriminatorMap.DiscriminatorProperty.TypeUsage),
                            discriminatorValue);
                    var discriminatorConstant = m_command.CreateNode(discriminatorValueOp);
                    var discriminatorPredicateOp = m_command.CreateComparisonOp(OpType.EQ);
                    var discriminatorPredicate = m_command.CreateNode(discriminatorPredicateOp, discriminator, discriminatorConstant);
                    children.Add(discriminatorPredicate);
                    children.Add(normalizedDiscriminatorConstant);
                }
            }

            // swap discriminator with case op normalizing the discriminator
            discriminator = m_command.CreateNode(normalizer, children);
            return discriminator;
        }
        /// <summary>
        /// Tracks discriminator metadata so that is can be used when constructing
        /// StructuredTypeInfo.
        /// </summary>
        public override Node Visit(DiscriminatedNewEntityOp op, Node n)
        {
            var relPropertyHashSet = new HashSet<RelProperty>();
            var relProperties = new List<RelProperty>();
            //
            // add references to each type produced by this node
            // Also, get the set of rel-properties for each of the types
            //
            foreach (var discriminatorTypePair in op.DiscriminatorMap.TypeMap)
            {
                EntityTypeBase entityType = discriminatorTypePair.Value;
                AddTypeReference(TypeUsage.Create(entityType));
                foreach (var relProperty in m_relPropertyHelper.GetRelProperties(entityType))
                {
                    relPropertyHashSet.Add(relProperty);
                }
            }
            relProperties = new List<RelProperty>(relPropertyHashSet);
            VisitScalarOpDefault(op, n);

            //
            // Now build out the set of missing rel-properties (if any)
            //

            // first, build the key expression
            var keyExpr = BuildKeyExpressionForNewEntityOp(op, n);

            var newChildren = new List<Node>();
            var firstRelPropertyNodeOffset = n.Children.Count - op.RelationshipProperties.Count;
            for (var i = 0; i < firstRelPropertyNodeOffset; i++)
            {
                newChildren.Add(n.Children[i]);
            }
            // 
            // Find the list of rel properties that have already been specified
            // 
            var prebuiltRelPropertyExprs = new Dictionary<RelProperty, Node>();
            for (int i = firstRelPropertyNodeOffset, j = 0; i < n.Children.Count; i++, j++)
            {
                prebuiltRelPropertyExprs[op.RelationshipProperties[j]] = n.Children[i];
            }

            //
            // Fill in the missing pieces
            //
            foreach (var relPropNode in BuildAllRelPropertyExpressions(op.EntitySet, relProperties, prebuiltRelPropertyExprs, keyExpr))
            {
                newChildren.Add(relPropNode);
            }

            Op newEntityOp = m_command.CreateDiscriminatedNewEntityOp(op.Type, op.DiscriminatorMap, op.EntitySet, relProperties);
            var newNode = m_command.CreateNode(newEntityOp, newChildren);

            return newNode;
        }
Exemple #4
0
 /// <summary>
 /// Copies a discriminated type constructor
 /// </summary>
 /// <param name="op">The Op to Copy</param>
 /// <param name="n">The Node that references the Op</param>
 /// <returns>A copy of the original Node that references a copy of the original Op</returns>
 public override Node Visit(DiscriminatedNewEntityOp op, Node n)
 {
     return(CopyDefault(m_destCmd.CreateDiscriminatedNewEntityOp(op.Type, op.DiscriminatorMap, op.EntitySet, op.RelationshipProperties), n));
 }
 /// <summary>
 ///     Visitor pattern method for DiscriminatedNewInstanceOp
 /// </summary>
 /// <param name="op"> The DiscriminatedNewInstanceOp being visited </param>
 /// <param name="n"> The Node that references the Op </param>
 public virtual void Visit(DiscriminatedNewEntityOp op, Node n)
 {
     VisitScalarOpDefault(op, n);
 }
Exemple #6
0
 public override void Visit(DiscriminatedNewEntityOp op, Node n)
 {
     VisitNewOp(op, n);
 }
Exemple #7
0
 // <summary>
 // Copies a discriminated type constructor
 // </summary>
 // <param name="op"> The Op to Copy </param>
 // <param name="n"> The Node that references the Op </param>
 // <returns> A copy of the original Node that references a copy of the original Op </returns>
 public override Node Visit(DiscriminatedNewEntityOp op, Node n)
 {
     return
         CopyDefault(
             m_destCmd.CreateDiscriminatedNewEntityOp(op.Type, op.DiscriminatorMap, op.EntitySet, op.RelationshipProperties), n);
 }