Beispiel #1
0
        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);
        }
Beispiel #2
0
        internal static DbQueryCommandTree SimplifyView(EntitySetBase extent, DbQueryCommandTree view)
        {
            var vs = new ViewSimplifier(extent);

            view = vs.Simplify(view);
            return(view);
        }
Beispiel #3
0
        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));
        }
Beispiel #4
0
        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;
 }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 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);
 }
Beispiel #8
0
        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));
        }