public override Expression Visit(DbCaseExpression expression) { List<Expression> cases = new List<Expression>() { this.Visit(expression.Else) }; for (int i = expression.When.Count - 1; i >= 0; i--) { cases.Add( Expression.Condition( this.Visit(expression.When[i]), this.Visit(expression.Then[i]), cases.Last())); } return cases.Last(); }
public override void Visit(DbCaseExpression e) { Check.NotNull(e, "e"); Begin(e); Dump(e.When, "Whens", "When"); Dump(e.Then, "Thens", "Then"); Dump(e.Else, "Else"); }
public override void Visit(DbCaseExpression expression) { throw new NotSupportedException("Visit(\"DbCaseExpression\") is not supported."); }
/// <summary> /// Visits the <see cref="DbCaseExpression"/>. /// </summary> /// <param name="expression">The expression.</param> public abstract void Visit(DbCaseExpression expression);
public override void Visit(DbCaseExpression e) { VisitExprKind(e.ExpressionKind); _key.Append('('); for (var idx = 0; idx < e.When.Count; idx++) { _key.Append("WHEN:("); e.When[idx].Accept(this); _key.Append(")THEN:("); e.Then[idx].Accept(this); } _key.Append("ELSE:("); e.Else.Accept(this); _key.Append("))"); }
/// <summary> /// Visitor pattern method for <see cref="DbCaseExpression" />. /// </summary> /// <param name="expression"> The DbCaseExpression that is being visited. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="expression" /> /// is null /// </exception> public override void Visit(DbCaseExpression expression) { // #433613: PreSharp warning 56506: Parameter 'expression' to this public method must be validated: A null-dereference can occur here. Check.NotNull(expression, "expression"); VisitExpressionList(expression.When); VisitExpressionList(expression.Then); VisitExpression(expression.Else); }
public override void Visit(DbCaseExpression expression) { Contract.Requires(expression != null); }
public override void Visit(DbCaseExpression expression) { }
private DbExpression AddFkRelatedEntityRefs(DbExpression viewConstructor) { // If the extent being simplified is not a C-Space entity set, or if it has already // been processed by the simplifier, then keep the original expression by returning // null. // if (this.doNotProcess) { return(null); } if (this.extent.BuiltInTypeKind != BuiltInTypeKind.EntitySet || this.extent.EntityContainer.DataSpace != DataSpace.CSpace) { this.doNotProcess = true; return(null); } // Get a reference to the entity set being simplified, and find all the foreign key // (foreign key) associations for which the association set references that entity set, // with either association end. // EntitySet targetSet = (EntitySet)this.extent; var relSets = targetSet.EntityContainer.BaseEntitySets .Where(es => es.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) .Cast <AssociationSet>() .Where(assocSet => assocSet.ElementType.IsForeignKey && assocSet.AssociationSetEnds.Any(se => se.EntitySet == targetSet) ) .ToList(); // If no foreign key association sets that reference the entity set are present, then // no further processing is necessary, because FK-based related entity references cannot // be computed and added to the entities constructed for the entity set. if (relSets.Count == 0) { this.doNotProcess = true; return(null); } // For every relationship set that references this entity set, the relationship type and // foreign key constraint are used to determine if the entity set is the dependent set. // If it is the dependent set, then it is possible to augment the view definition with a // related entity ref that represents the navigation of the relationship set's relationship // from the dependent end (this entity set) to the the principal end (the entity set that // is referenced by the other association set end of the relationship set). // var principalSetsAndDependentTypes = new HashSet <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint> >(); foreach (AssociationSet relSet in relSets) { // Retrieve the single referential constraint from the foreign key association, and // use it to determine whether the association set end that represents the dependent // end of the association references this entity set. // var fkConstraint = relSet.ElementType.ReferentialConstraints[0]; var dependentSetEnd = relSet.AssociationSetEnds[fkConstraint.ToRole.Name]; if (dependentSetEnd.EntitySet == targetSet) { EntityType requiredSourceNavType = (EntityType)TypeHelpers.GetEdmType <RefType>(dependentSetEnd.CorrespondingAssociationEndMember.TypeUsage).ElementType; var principalSetEnd = relSet.AssociationSetEnds[fkConstraint.FromRole.Name]; // Record the entity type that an element of this dependent entity set must have in order // to be a valid navigation source for the relationship set's relationship, along with the // association set end for the destination (principal) end of the navigation and the FK // constraint that is associated with the relationship type. This information may be used // later to construct a related entity ref for any entity constructor expression in the view // that produces an entity of the required source type or a subtype. // principalSetsAndDependentTypes.Add(Tuple.Create(requiredSourceNavType, principalSetEnd, fkConstraint)); } } // If no foreign key association sets that use the entity set as the dependent set are present, // then no further processing is possible, since FK-based related entity refs can only be added // to the view definition for navigations from the dependent end of the relationship to the principal. // if (principalSetsAndDependentTypes.Count == 0) { this.doNotProcess = true; return(null); } // This rule supports a view that is capped with a projection of the form // (input).Project(x => new Entity()) // or // (input).Project(x => CASE WHEN (condition1) THEN new Entity1() ELSE WHEN (condition2) THEN new Entity2()... ELSE new EntityN()) // where every new instance expression Entity1()...EntityN() constructs an entity of a type // that is compatible with the entity set's element type. // Here, the list of all DbNewInstanceExpressions contained in the projection is remembered, // along with any CASE statement conditions, if present. These expressions will be updated // if necessary and used to build a new capping projection if any of the entity constructors // are augmented with FK-based related entity references. // DbProjectExpression entityProject = (DbProjectExpression)viewConstructor; List <DbNewInstanceExpression> constructors = new List <DbNewInstanceExpression>(); List <DbExpression> conditions = null; if (entityProject.Projection.ExpressionKind == DbExpressionKind.Case) { // If the projection is a DbCaseExpression, then every result must be a DbNewInstanceExpression DbCaseExpression discriminatedConstructor = (DbCaseExpression)entityProject.Projection; conditions = new List <DbExpression>(discriminatedConstructor.When.Count); for (int idx = 0; idx < discriminatedConstructor.When.Count; idx++) { conditions.Add(discriminatedConstructor.When[idx]); constructors.Add((DbNewInstanceExpression)discriminatedConstructor.Then[idx]); } constructors.Add((DbNewInstanceExpression)discriminatedConstructor.Else); } else { // Otherwise, the projection must be a single DbNewInstanceExpression constructors.Add((DbNewInstanceExpression)entityProject.Projection); } bool rebuildView = false; for (int idx = 0; idx < constructors.Count; idx++) { DbNewInstanceExpression entityConstructor = constructors[idx]; EntityType constructedEntityType = TypeHelpers.GetEdmType <EntityType>(entityConstructor.ResultType); List <DbRelatedEntityRef> relatedRefs = principalSetsAndDependentTypes .Where(psdt => constructedEntityType == psdt.Item1 || constructedEntityType.IsSubtypeOf(psdt.Item1)) .Select(psdt => RelatedEntityRefFromAssociationSetEnd(constructedEntityType, entityConstructor, psdt.Item2, psdt.Item3)).ToList(); if (relatedRefs.Count > 0) { if (entityConstructor.HasRelatedEntityReferences) { relatedRefs = entityConstructor.RelatedEntityReferences.Concat(relatedRefs).ToList(); } entityConstructor = DbExpressionBuilder.CreateNewEntityWithRelationshipsExpression(constructedEntityType, entityConstructor.Arguments, relatedRefs); constructors[idx] = entityConstructor; rebuildView = true; } } // Default to returning null to indicate that this rule did not produce a modified expression // DbExpression result = null; if (rebuildView) { // rebuildView is true, so entity constructing DbNewInstanceExpression(s) were encountered // and updated with additional related entity refs. The DbProjectExpression that caps the // view definition therefore needs to be rebuilt and returned as the result of this rule. // if (conditions != null) { // The original view definition projection was a DbCaseExpression. // The new expression is also a DbCaseExpression that uses the conditions from the // original expression together with the updated result expressions to produce the // new capping projection. // List <DbExpression> whens = new List <DbExpression>(conditions.Count); List <DbExpression> thens = new List <DbExpression>(conditions.Count); for (int idx = 0; idx < conditions.Count; idx++) { whens.Add(conditions[idx]); thens.Add(constructors[idx]); } result = entityProject.Input.Project(DbExpressionBuilder.Case(whens, thens, constructors[conditions.Count])); } else { // Otherwise, the capping projection consists entirely of the updated DbNewInstanceExpression. // result = entityProject.Input.Project(constructors[0]); } } // Regardless of whether or not the view was updated, this rule should not be applied again during rule processing this.doNotProcess = true; return(result); }
public override void Visit(DbCaseExpression expression) { throw new NotImplementedException(); }
private DbExpression AddFkRelatedEntityRefs(DbExpression viewConstructor) { if (this.doNotProcess) { return((DbExpression)null); } if (this.extent.BuiltInTypeKind != BuiltInTypeKind.EntitySet || this.extent.EntityContainer.DataSpace != DataSpace.CSpace) { this.doNotProcess = true; return((DbExpression)null); } EntitySet targetSet = (EntitySet)this.extent; List <AssociationSet> list1 = targetSet.EntityContainer.BaseEntitySets.Where <EntitySetBase>((Func <EntitySetBase, bool>)(es => es.BuiltInTypeKind == BuiltInTypeKind.AssociationSet)).Cast <AssociationSet>().Where <AssociationSet>((Func <AssociationSet, bool>)(assocSet => { if (assocSet.ElementType.IsForeignKey) { return(assocSet.AssociationSetEnds.Any <AssociationSetEnd>((Func <AssociationSetEnd, bool>)(se => se.EntitySet == targetSet))); } return(false); })).ToList <AssociationSet>(); if (list1.Count == 0) { this.doNotProcess = true; return((DbExpression)null); } HashSet <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint> > source = new HashSet <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint> >(); foreach (AssociationSet associationSet in list1) { ReferentialConstraint referentialConstraint = associationSet.ElementType.ReferentialConstraints[0]; AssociationSetEnd associationSetEnd1 = associationSet.AssociationSetEnds[referentialConstraint.ToRole.Name]; if (associationSetEnd1.EntitySet == targetSet) { EntityType elementType = (EntityType)TypeHelpers.GetEdmType <RefType>(associationSetEnd1.CorrespondingAssociationEndMember.TypeUsage).ElementType; AssociationSetEnd associationSetEnd2 = associationSet.AssociationSetEnds[referentialConstraint.FromRole.Name]; source.Add(Tuple.Create <EntityType, AssociationSetEnd, ReferentialConstraint>(elementType, associationSetEnd2, referentialConstraint)); } } if (source.Count == 0) { this.doNotProcess = true; return((DbExpression)null); } DbProjectExpression projectExpression = (DbProjectExpression)viewConstructor; List <DbNewInstanceExpression> instanceExpressionList = new List <DbNewInstanceExpression>(); List <DbExpression> dbExpressionList1 = (List <DbExpression>)null; if (projectExpression.Projection.ExpressionKind == DbExpressionKind.Case) { DbCaseExpression projection = (DbCaseExpression)projectExpression.Projection; dbExpressionList1 = new List <DbExpression>(projection.When.Count); for (int index = 0; index < projection.When.Count; ++index) { dbExpressionList1.Add(projection.When[index]); instanceExpressionList.Add((DbNewInstanceExpression)projection.Then[index]); } instanceExpressionList.Add((DbNewInstanceExpression)projection.Else); } else { instanceExpressionList.Add((DbNewInstanceExpression)projectExpression.Projection); } bool flag = false; for (int index = 0; index < instanceExpressionList.Count; ++index) { DbNewInstanceExpression entityConstructor = instanceExpressionList[index]; EntityType constructedEntityType = TypeHelpers.GetEdmType <EntityType>(entityConstructor.ResultType); List <DbRelatedEntityRef> list2 = source.Where <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint> >((Func <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint>, bool>)(psdt => { if (constructedEntityType != psdt.Item1) { return(constructedEntityType.IsSubtypeOf((EdmType)psdt.Item1)); } return(true); })).Select <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint>, DbRelatedEntityRef>((Func <Tuple <EntityType, AssociationSetEnd, ReferentialConstraint>, DbRelatedEntityRef>)(psdt => ViewSimplifier.RelatedEntityRefFromAssociationSetEnd(constructedEntityType, entityConstructor, psdt.Item2, psdt.Item3))).ToList <DbRelatedEntityRef>(); if (list2.Count > 0) { if (entityConstructor.HasRelatedEntityReferences) { list2 = entityConstructor.RelatedEntityReferences.Concat <DbRelatedEntityRef>((IEnumerable <DbRelatedEntityRef>)list2).ToList <DbRelatedEntityRef>(); } entityConstructor = DbExpressionBuilder.CreateNewEntityWithRelationshipsExpression(constructedEntityType, entityConstructor.Arguments, (IList <DbRelatedEntityRef>)list2); instanceExpressionList[index] = entityConstructor; flag = true; } } DbExpression dbExpression = (DbExpression)null; if (flag) { if (dbExpressionList1 != null) { List <DbExpression> dbExpressionList2 = new List <DbExpression>(dbExpressionList1.Count); List <DbExpression> dbExpressionList3 = new List <DbExpression>(dbExpressionList1.Count); for (int index = 0; index < dbExpressionList1.Count; ++index) { dbExpressionList2.Add(dbExpressionList1[index]); dbExpressionList3.Add((DbExpression)instanceExpressionList[index]); } dbExpression = (DbExpression)projectExpression.Input.Project((DbExpression)DbExpressionBuilder.Case((IEnumerable <DbExpression>)dbExpressionList2, (IEnumerable <DbExpression>)dbExpressionList3, (DbExpression)instanceExpressionList[dbExpressionList1.Count])); } else { dbExpression = (DbExpression)projectExpression.Input.Project((DbExpression)instanceExpressionList[0]); } } this.doNotProcess = true; return(dbExpression); }
private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression) { DbProjectExpression projectExpression = (DbProjectExpression)expression; DbFilterExpression booleanColumnFilter = (DbFilterExpression)projectExpression.Input.Expression; DbProjectExpression expression1 = (DbProjectExpression)booleanColumnFilter.Input.Expression; DbFilterExpression expression2 = (DbFilterExpression)expression1.Input.Expression; List <DbExpression> list1 = ViewSimplifier.FlattenOr(booleanColumnFilter.Predicate).ToList <DbExpression>(); List <DbPropertyExpression> list2 = list1.OfType <DbPropertyExpression>().Where <DbPropertyExpression>((Func <DbPropertyExpression, bool>)(px => { if (px.Instance.ExpressionKind == DbExpressionKind.VariableReference) { return(((DbVariableReferenceExpression)px.Instance).VariableName == booleanColumnFilter.Input.VariableName); } return(false); })).ToList <DbPropertyExpression>(); if (list1.Count != list2.Count) { return((DbExpression)null); } List <string> list3 = list2.Select <DbPropertyExpression, string>((Func <DbPropertyExpression, string>)(px => px.Property.Name)).ToList <string>(); Dictionary <object, DbComparisonExpression> discriminatorPredicates = new Dictionary <object, DbComparisonExpression>(); if (!TypeSemantics.IsEntityType(expression2.Input.VariableType) || !ViewSimplifier.TryMatchDiscriminatorPredicate(expression2, (Action <DbComparisonExpression, object>)((compEx, discValue) => discriminatorPredicates.Add(discValue, compEx)))) { return((DbExpression)null); } EdmProperty property1 = (EdmProperty)((DbPropertyExpression)discriminatorPredicates.First <KeyValuePair <object, DbComparisonExpression> >().Value.Left).Property; DbNewInstanceExpression projection1 = (DbNewInstanceExpression)expression1.Projection; RowType edmType = TypeHelpers.GetEdmType <RowType>(projection1.ResultType); Dictionary <string, DbComparisonExpression> dictionary1 = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbComparisonExpression> dictionary2 = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbExpression> propertyValues = new Dictionary <string, DbExpression>(projection1.Arguments.Count); for (int index = 0; index < projection1.Arguments.Count; ++index) { string name = edmType.Properties[index].Name; DbExpression dbExpression = projection1.Arguments[index]; if (list3.Contains(name)) { if (dbExpression.ExpressionKind != DbExpressionKind.Case) { return((DbExpression)null); } DbCaseExpression dbCaseExpression = (DbCaseExpression)dbExpression; if (dbCaseExpression.When.Count != 1 || !TypeSemantics.IsBooleanType(dbCaseExpression.Then[0].ResultType) || (!TypeSemantics.IsBooleanType(dbCaseExpression.Else.ResultType) || dbCaseExpression.Then[0].ExpressionKind != DbExpressionKind.Constant) || (dbCaseExpression.Else.ExpressionKind != DbExpressionKind.Constant || !(bool)((DbConstantExpression)dbCaseExpression.Then[0]).Value || (bool)((DbConstantExpression)dbCaseExpression.Else).Value)) { return((DbExpression)null); } DbPropertyExpression property2; object key; if (!ViewSimplifier.TryMatchPropertyEqualsValue(dbCaseExpression.When[0], expression1.Input.VariableName, out property2, out key) || property2.Property != property1 || !discriminatorPredicates.ContainsKey(key)) { return((DbExpression)null); } dictionary1.Add(name, discriminatorPredicates[key]); dictionary2.Add(name, (DbComparisonExpression)dbCaseExpression.When[0]); } else { propertyValues.Add(name, dbExpression); } } DbExpression predicate = Helpers.BuildBalancedTreeInPlace <DbExpression>((IList <DbExpression>) new List <DbExpression>((IEnumerable <DbExpression>)dictionary1.Values), (Func <DbExpression, DbExpression, DbExpression>)((left, right) => (DbExpression)left.Or(right))); DbFilterExpression input = expression2.Input.Filter(predicate); DbCaseExpression projection2 = (DbCaseExpression)projectExpression.Projection; List <DbExpression> dbExpressionList1 = new List <DbExpression>(projection2.When.Count); List <DbExpression> dbExpressionList2 = new List <DbExpression>(projection2.Then.Count); for (int index = 0; index < projection2.When.Count; ++index) { DbPropertyExpression propertyExpression = (DbPropertyExpression)projection2.When[index]; DbNewInstanceExpression instanceExpression = (DbNewInstanceExpression)projection2.Then[index]; DbComparisonExpression comparisonExpression; if (!dictionary2.TryGetValue(propertyExpression.Property.Name, out comparisonExpression)) { return((DbExpression)null); } dbExpressionList1.Add((DbExpression)comparisonExpression); DbExpression dbExpression = ViewSimplifier.ValueSubstituter.Substitute((DbExpression)instanceExpression, projectExpression.Input.VariableName, propertyValues); dbExpressionList2.Add(dbExpression); } DbExpression elseExpression = ViewSimplifier.ValueSubstituter.Substitute(projection2.Else, projectExpression.Input.VariableName, propertyValues); DbCaseExpression dbCaseExpression1 = DbExpressionBuilder.Case((IEnumerable <DbExpression>)dbExpressionList1, (IEnumerable <DbExpression>)dbExpressionList2, elseExpression); return((DbExpression)input.BindAs(expression1.Input.VariableName).Project((DbExpression)dbCaseExpression1)); }
/// <summary> /// Visitor pattern method for <see cref="DbCaseExpression"/>. /// </summary> /// <param name="expression">The DbCaseExpression that is being visited.</param> /// <exception cref="ArgumentNullException"><paramref name="expression"/> is null</exception> public override void Visit(DbCaseExpression expression) { VisitExpressionList(expression.When); VisitExpressionList(expression.Then); VisitExpression(expression.Else); }
public override DbExpressionEntitySetInfo Visit(DbCaseExpression expression) { return(null); }
/// <summary> /// Visitor pattern method for <see cref="DbCaseExpression" />. /// </summary> /// <param name="expression"> The DbCaseExpression that is being visited. </param> /// <exception cref="ArgumentNullException"> /// <paramref name="expression" /> /// is null /// </exception> public override void Visit(DbCaseExpression expression) { Check.NotNull(expression, "expression"); VisitExpressionList(expression.When); VisitExpressionList(expression.Then); VisitExpression(expression.Else); }
/// <summary> /// Converts the DbExpression equivalent of: /// /// SELECT CASE /// WHEN a._from0 THEN SUBTYPE1() /// ... /// WHEN a._from[n-2] THEN SUBTYPE_n-1() /// ELSE SUBTYPE_n /// FROM /// SELECT /// b.C1..., b.Cn /// CASE WHEN b.Discriminator = SUBTYPE1_Value THEN true ELSE false AS _from0 /// ... /// CASE WHEN b.Discriminator = SUBTYPE_n_Value THEN true ELSE false AS _from[n-1] /// FROM TSet AS b /// WHERE b.Discriminator = SUBTYPE1_Value... OR x.Discriminator = SUBTYPE_n_Value /// AS a /// WHERE a._from0... OR a._from[n-1] /// /// into the DbExpression equivalent of the following, which is matched as a TPH discriminator /// by the <see cref="System.Data.Mapping.ViewGeneration.GeneratedView"/> class and so allows a <see cref="System.Data.Mapping.ViewGeneration.DiscriminatorMap"/> /// to be produced for the view, which would not otherwise be possible. Note that C1 through Cn /// are only allowed to be scalars or complex type constructors based on direct property references /// to the store entity set's scalar properties. /// /// SELECT CASE /// WHEN y.Discriminator = SUBTTYPE1_Value THEN SUBTYPE1() /// ... /// WHEN y.Discriminator = SUBTYPE_n-1_Value THEN SUBTYPE_n-1() /// ELSE SUBTYPE_n() /// FROM /// SELECT x.C1..., x.Cn, Discriminator FROM TSet AS x /// WHERE x.Discriminator = SUBTYPE1_Value... OR x.Discriminator = SUBTYPE_n_Value /// AS y /// /// </summary> private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression) { DbProjectExpression entityProjection = (DbProjectExpression)expression; DbFilterExpression booleanColumnFilter = (DbFilterExpression)entityProjection.Input.Expression; DbProjectExpression rowProjection = (DbProjectExpression)booleanColumnFilter.Input.Expression; DbFilterExpression discriminatorFilter = (DbFilterExpression)rowProjection.Input.Expression; List <DbExpression> predicates = FlattenOr(booleanColumnFilter.Predicate).ToList(); List <DbPropertyExpression> propertyPredicates = predicates.OfType <DbPropertyExpression>() .Where(px => px.Instance.ExpressionKind == DbExpressionKind.VariableReference && ((DbVariableReferenceExpression)px.Instance).VariableName == booleanColumnFilter.Input.VariableName).ToList(); if (predicates.Count != propertyPredicates.Count) { return(null); } List <string> predicateColumnNames = propertyPredicates.Select(px => px.Property.Name).ToList(); Dictionary <object, DbComparisonExpression> discriminatorPredicates = new Dictionary <object, DbComparisonExpression>(); if (!TypeSemantics.IsEntityType(discriminatorFilter.Input.VariableType) || !TryMatchDiscriminatorPredicate(discriminatorFilter, (compEx, discValue) => discriminatorPredicates.Add(discValue, compEx))) { return(null); } EdmProperty discriminatorProp = (EdmProperty)((DbPropertyExpression)((DbComparisonExpression)discriminatorPredicates.First().Value).Left).Property; DbNewInstanceExpression rowConstructor = (DbNewInstanceExpression)rowProjection.Projection; RowType resultRow = TypeHelpers.GetEdmType <RowType>(rowConstructor.ResultType); Dictionary <string, DbComparisonExpression> inputPredicateMap = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbComparisonExpression> selectorPredicateMap = new Dictionary <string, DbComparisonExpression>(); Dictionary <string, DbExpression> columnValues = new Dictionary <string, DbExpression>(rowConstructor.Arguments.Count); for (int idx = 0; idx < rowConstructor.Arguments.Count; idx++) { string propName = resultRow.Properties[idx].Name; DbExpression columnVal = rowConstructor.Arguments[idx]; if (predicateColumnNames.Contains(propName)) { if (columnVal.ExpressionKind != DbExpressionKind.Case) { return(null); } DbCaseExpression casePredicate = (DbCaseExpression)columnVal; if (casePredicate.When.Count != 1 || !TypeSemantics.IsBooleanType(casePredicate.Then[0].ResultType) || !TypeSemantics.IsBooleanType(casePredicate.Else.ResultType) || casePredicate.Then[0].ExpressionKind != DbExpressionKind.Constant || casePredicate.Else.ExpressionKind != DbExpressionKind.Constant || (bool)((DbConstantExpression)casePredicate.Then[0]).Value != true || (bool)((DbConstantExpression)casePredicate.Else).Value != false) { return(null); } DbPropertyExpression comparedProp; object constValue; if (!TryMatchPropertyEqualsValue(casePredicate.When[0], rowProjection.Input.VariableName, out comparedProp, out constValue) || comparedProp.Property != discriminatorProp || !discriminatorPredicates.ContainsKey(constValue)) { return(null); } inputPredicateMap.Add(propName, discriminatorPredicates[constValue]); selectorPredicateMap.Add(propName, (DbComparisonExpression)casePredicate.When[0]); } else { columnValues.Add(propName, columnVal); } } // Build a new discriminator-based filter that only includes the same rows allowed by the higher '_from0' column-based filter DbExpression newDiscriminatorPredicate = Helpers.BuildBalancedTreeInPlace <DbExpression>(new List <DbExpression>(inputPredicateMap.Values), (left, right) => DbExpressionBuilder.Or(left, right)); discriminatorFilter = discriminatorFilter.Input.Filter(newDiscriminatorPredicate); DbCaseExpression entitySelector = (DbCaseExpression)entityProjection.Projection; List <DbExpression> newWhens = new List <DbExpression>(entitySelector.When.Count); List <DbExpression> newThens = new List <DbExpression>(entitySelector.Then.Count); for (int idx = 0; idx < entitySelector.When.Count; idx++) { DbPropertyExpression propWhen = (DbPropertyExpression)entitySelector.When[idx]; DbNewInstanceExpression entityThen = (DbNewInstanceExpression)entitySelector.Then[idx]; DbComparisonExpression discriminatorWhen; if (!selectorPredicateMap.TryGetValue(propWhen.Property.Name, out discriminatorWhen)) { return(null); } newWhens.Add(discriminatorWhen); DbExpression inputBoundEntityConstructor = ValueSubstituter.Substitute(entityThen, entityProjection.Input.VariableName, columnValues); newThens.Add(inputBoundEntityConstructor); } DbExpression newElse = ValueSubstituter.Substitute(entitySelector.Else, entityProjection.Input.VariableName, columnValues); DbCaseExpression newEntitySelector = DbExpressionBuilder.Case(newWhens, newThens, newElse); DbExpression result = discriminatorFilter.BindAs(rowProjection.Input.VariableName).Project(newEntitySelector); return(result); }
public override TReturn Visit(DbCaseExpression expression) { Check.NotNull(expression, "expression"); throw ConstructNotSupportedException(expression); }
public override void Visit(DbCaseExpression e) { Begin(e); Dump(e.When, "Whens", "When"); Dump(e.Then, "Thens", "Then"); Dump(e.Else, "Else"); }
internal static bool TryCreateDiscriminatorMap( EntitySet entitySet, DbExpression queryView, out DiscriminatorMap discriminatorMap) { discriminatorMap = (DiscriminatorMap)null; if (queryView.ExpressionKind != DbExpressionKind.Project) { return(false); } DbProjectExpression projectExpression = (DbProjectExpression)queryView; if (projectExpression.Projection.ExpressionKind != DbExpressionKind.Case) { return(false); } DbCaseExpression projection = (DbCaseExpression)projectExpression.Projection; if (projectExpression.Projection.ResultType.EdmType.BuiltInTypeKind != BuiltInTypeKind.EntityType || projectExpression.Input.Expression.ExpressionKind != DbExpressionKind.Filter) { return(false); } DbFilterExpression expression1 = (DbFilterExpression)projectExpression.Input.Expression; HashSet <object> discriminatorDomain = new HashSet <object>(); if (!ViewSimplifier.TryMatchDiscriminatorPredicate(expression1, (Action <DbComparisonExpression, object>)((equalsExp, discriminatorValue) => discriminatorDomain.Add(discriminatorValue)))) { return(false); } List <KeyValuePair <object, EntityType> > keyValuePairList = new List <KeyValuePair <object, EntityType> >(); Dictionary <EdmProperty, DbExpression> propertyMap = new Dictionary <EdmProperty, DbExpression>(); Dictionary <RelProperty, DbExpression> relPropertyMap = new Dictionary <RelProperty, DbExpression>(); Dictionary <EntityType, List <RelProperty> > typeToRelPropertyMap = new Dictionary <EntityType, List <RelProperty> >(); DbPropertyExpression discriminator = (DbPropertyExpression)null; EdmProperty edmProperty = (EdmProperty)null; for (int index = 0; index < projection.When.Count; ++index) { DbExpression expression2 = projection.When[index]; DbExpression then = projection.Then[index]; string variableName = projectExpression.Input.VariableName; DbPropertyExpression property; object key; if (!ViewSimplifier.TryMatchPropertyEqualsValue(expression2, variableName, out property, out key)) { return(false); } if (edmProperty == null) { edmProperty = (EdmProperty)property.Property; } else if (edmProperty != property.Property) { return(false); } discriminator = property; EntityType entityType; if (!DiscriminatorMap.TryMatchEntityTypeConstructor(then, propertyMap, relPropertyMap, typeToRelPropertyMap, out entityType)) { return(false); } keyValuePairList.Add(new KeyValuePair <object, EntityType>(key, entityType)); discriminatorDomain.Remove(key); } EntityType entityType1; if (1 != discriminatorDomain.Count || projection.Else == null || !DiscriminatorMap.TryMatchEntityTypeConstructor(projection.Else, propertyMap, relPropertyMap, typeToRelPropertyMap, out entityType1)) { return(false); } keyValuePairList.Add(new KeyValuePair <object, EntityType>(discriminatorDomain.Single <object>(), entityType1)); if (!DiscriminatorMap.CheckForMissingRelProperties(relPropertyMap, typeToRelPropertyMap) || keyValuePairList.Select <KeyValuePair <object, EntityType>, object>((Func <KeyValuePair <object, EntityType>, object>)(map => map.Key)).Distinct <object>((IEqualityComparer <object>)TrailingSpaceComparer.Instance).Count <object>() != keyValuePairList.Count) { return(false); } discriminatorMap = new DiscriminatorMap(discriminator, keyValuePairList, propertyMap, relPropertyMap, entitySet); return(true); }
/// <summary> /// Visitor pattern method for DbCaseExpression. /// </summary> /// <param name="expression"> The DbCaseExpression that is being visited. </param> public abstract void Visit(DbCaseExpression expression);
public override DbExpressionEntitySetInfo Visit(DbCaseExpression expression) { Check.NotNull(expression, "expression"); return(null); }
public override void Visit(DbCaseExpression expression) { throw new NotSupportedException("Visit(\"CaseExpression\") is not supported."); }
/// <summary> /// Implements the visitor pattern for <see cref="T:System.Data.Common.CommandTrees.DbCaseExpression"/>. /// </summary> /// <param name="expression">The <see cref="T:System.Data.Common.CommandTrees.DbCaseExpression"/> that is visited.</param> public override void Visit(DbCaseExpression expression) { if (expression == null) { throw new ArgumentNullException("expression"); } foreach (DbExpression e in expression.When) { e.Accept(this); } foreach (DbExpression e in expression.Then) { e.Accept(this); } expression.Else.Accept(this); }
public override void Visit(DbCaseExpression expression) { if (expression == null) throw new ArgumentException("expression"); VisitExpressionList(expression.When); VisitExpressionList(expression.Then); VisitExpression(expression.Else); }
public override IPostgreSqlFragment Visit(DbCaseExpression expression) { throw new NotImplementedException(); }