/// <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; }
/// <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); }
public override void Visit(DiscriminatedNewEntityOp op, Node n) { VisitNewOp(op, n); }
// <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); }