internal static bool TryMatchDiscriminatorPredicate( DbFilterExpression filter, Action <DbComparisonExpression, object> onMatchedComparison) { EdmProperty edmProperty = (EdmProperty)null; foreach (DbExpression expression in ViewSimplifier.FlattenOr(filter.Predicate)) { DbPropertyExpression property; object obj; if (!ViewSimplifier.TryMatchPropertyEqualsValue(expression, filter.Input.VariableName, out property, out obj)) { return(false); } if (edmProperty == null) { edmProperty = (EdmProperty)property.Property; } else if (edmProperty != property.Property) { return(false); } onMatchedComparison((DbComparisonExpression)expression, obj); } return(true); }
internal static DbQueryCommandTree SimplifyView(EntitySetBase extent, DbQueryCommandTree view) { var vs = new ViewSimplifier(extent); view = vs.Simplify(view); return(view); }
private static DbExpression SimplifyCaseStatement(DbExpression expression) { DbCaseExpression dbCaseExpression = (DbCaseExpression)expression; bool flag = false; List <DbExpression> dbExpressionList = new List <DbExpression>(dbCaseExpression.When.Count); foreach (DbExpression predicate in (IEnumerable <DbExpression>)dbCaseExpression.When) { DbExpression simplified; if (ViewSimplifier.TrySimplifyPredicate(predicate, out simplified)) { dbExpressionList.Add(simplified); flag = true; } else { dbExpressionList.Add(predicate); } } if (!flag) { return((DbExpression)null); } return((DbExpression)DbExpressionBuilder.Case((IEnumerable <DbExpression>)dbExpressionList, (IEnumerable <DbExpression>)dbCaseExpression.Then, dbCaseExpression.Else)); }
internal static bool TryMatchPropertyEqualsValue( DbExpression expression, string propertyVariable, out DbPropertyExpression property, out object value) { property = (DbPropertyExpression)null; value = (object)null; if (expression.ExpressionKind != DbExpressionKind.Equals) { return(false); } DbBinaryExpression binaryExpression = (DbBinaryExpression)expression; if (binaryExpression.Left.ExpressionKind != DbExpressionKind.Property) { return(false); } property = (DbPropertyExpression)binaryExpression.Left; return(ViewSimplifier.TryMatchConstant(binaryExpression.Right, out value) && property.Instance.ExpressionKind == DbExpressionKind.VariableReference && !(((DbVariableReferenceExpression)property.Instance).VariableName != propertyVariable)); }
internal static DbQueryCommandTree SimplifyView(EntitySetBase extent, DbQueryCommandTree view) { var vs = new ViewSimplifier(extent); view = vs.Simplify(view); return view; }
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 bool TryMatchConstant(DbExpression expression, out object value) { if (expression.ExpressionKind == DbExpressionKind.Constant) { value = ((DbConstantExpression)expression).Value; return(true); } if (expression.ExpressionKind == DbExpressionKind.Cast && expression.ResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType && ViewSimplifier.TryMatchConstant(((DbUnaryExpression)expression).Argument, out value)) { PrimitiveType edmType = (PrimitiveType)expression.ResultType.EdmType; value = Convert.ChangeType(value, edmType.ClrEquivalentType, (IFormatProvider)CultureInfo.InvariantCulture); return(true); } value = (object)null; return(false); }
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)); }