コード例 #1
0
        internal DbIsOfExpression(DbExpressionKind isOfKind, TypeUsage booleanResultType, DbExpression argument, TypeUsage isOfType)
            : base(isOfKind, booleanResultType, argument)
        {
            Debug.Assert(DbExpressionKind.IsOf == this.ExpressionKind || DbExpressionKind.IsOfOnly == this.ExpressionKind, string.Format(CultureInfo.InvariantCulture, "Invalid DbExpressionKind used in DbIsOfExpression: {0}", Enum.GetName(typeof(DbExpressionKind), this.ExpressionKind)));
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsOfExpression requires a Boolean result type");

            this._ofType = isOfType;
        }
コード例 #2
0
 internal static bool SupportsCastToString(TypeUsage typeUsage)
 {
     return(TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.String) ||
            TypeSemantics.IsNumericType(typeUsage) ||
            TypeSemantics.IsBooleanType(typeUsage) ||
            TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTime) ||
            TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTimeOffset) ||
            TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Time) ||
            TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Guid));
 }
コード例 #3
0
 internal virtual ConstantBaseOp CreateConstantOp(TypeUsage type, object value)
 {
     if (value == null)
     {
         return((ConstantBaseOp) new NullOp(type));
     }
     if (TypeSemantics.IsBooleanType(type))
     {
         return((ConstantBaseOp) new InternalConstantOp(type, value));
     }
     return((ConstantBaseOp) new ConstantOp(type, value));
 }
コード例 #4
0
        internal DbInExpression(TypeUsage booleanResultType, DbExpression item, DbExpressionList list)
            : base(DbExpressionKind.In, booleanResultType)
        {
            DebugCheck.NotNull(item);
            DebugCheck.NotNull(list);
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbInExpression must have a Boolean result type");
            Debug.Assert(
                list.All(e => TypeSemantics.IsEqual(e.ResultType, item.ResultType)),
                "DbInExpression requires the same result type for the input expressions");

            _item = item;
            _list = list;
        }
コード例 #5
0
        internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape)
            : base(DbExpressionKind.Like, booleanResultType)
        {
            Debug.Assert(input != null, "DbLikeExpression argument cannot be null");
            Debug.Assert(pattern != null, "DbLikeExpression pattern cannot be null");
            Debug.Assert(escape != null, "DbLikeExpression escape cannot be null");
            Debug.Assert(TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type");
            Debug.Assert(TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type");
            Debug.Assert(TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type");
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type");

            this._argument = input;
            this._pattern  = pattern;
            this._escape   = escape;
        }
コード例 #6
0
 internal DbComparisonExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpression left, DbExpression right)
     : base(kind, booleanResultType, left, right)
 {
     Debug.Assert(left != null, "DbComparisonExpression left cannot be null");
     Debug.Assert(right != null, "DbComparisonExpression right cannot be null");
     Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbComparisonExpression result type must be a Boolean type");
     Debug.Assert(
         DbExpressionKind.Equals == kind ||
         DbExpressionKind.LessThan == kind ||
         DbExpressionKind.LessThanOrEquals == kind ||
         DbExpressionKind.GreaterThan == kind ||
         DbExpressionKind.GreaterThanOrEquals == kind ||
         DbExpressionKind.NotEquals == kind,
         "Invalid DbExpressionKind used in DbComparisonExpression: " + Enum.GetName(typeof(DbExpressionKind), kind)
         );
 }
コード例 #7
0
        public override void Visit(CaseOp op, Node n)
        {
            VisitScalarOpDefault(op, n);
            Assert((n.Children.Count >= 3 && n.Children.Count % 2 == 1),
                   "CaseOp: Expected odd number of arguments, and at least 3; found {0}", n.Children.Count);

            // Validate that each when statement is of type Boolean
            for (int i = 0; i < n.Children.Count - 1; i += 2)
            {
                Assert(TypeSemantics.IsBooleanType(n.Children[i].Op.Type), "Encountered a when node with a non-boolean return type");
            }

            // Ensure that the then clauses, the else clause and the result type are all the same
            for (int i = 1; i < n.Children.Count - 1; i += 2)
            {
                AssertEqualTypes(n.Op.Type, n.Children[i].Op.Type);
            }
            AssertEqualTypes(n.Op.Type, n.Children[n.Children.Count - 1].Op.Type);
        }
コード例 #8
0
        internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape)
            : base(DbExpressionKind.Like, booleanResultType)
        {
            DebugCheck.NotNull(input);
            DebugCheck.NotNull(pattern);
            DebugCheck.NotNull(escape);
            Debug.Assert(
                TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String),
                "DbLikeExpression argument must have a string result type");
            Debug.Assert(
                TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String),
                "DbLikeExpression pattern must have a string result type");
            Debug.Assert(
                TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String),
                "DbLikeExpression escape must have a string result type");
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type");

            _argument = input;
            _pattern  = pattern;
            _escape   = escape;
        }
コード例 #9
0
 internal DbIsNullExpression(TypeUsage booleanResultType, DbExpression arg)
     : base(DbExpressionKind.IsNull, booleanResultType, arg)
 {
     Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsNullExpression requires a Boolean result type");
 }
コード例 #10
0
        private static DbExpression SimplifyNestedTphDiscriminator(DbExpression expression)
        {
            var entityProjection    = (DbProjectExpression)expression;
            var booleanColumnFilter = (DbFilterExpression)entityProjection.Input.Expression;
            var rowProjection       = (DbProjectExpression)booleanColumnFilter.Input.Expression;
            var discriminatorFilter = (DbFilterExpression)rowProjection.Input.Expression;

            var predicates         = FlattenOr(booleanColumnFilter.Predicate).ToList();
            var 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);
            }

            var predicateColumnNames = propertyPredicates.Select(px => px.Property.Name).ToList();

            var discriminatorPredicates = new Dictionary <object, DbComparisonExpression>();

            if (!TypeSemantics.IsEntityType(discriminatorFilter.Input.VariableType)
                ||
                !TryMatchDiscriminatorPredicate(discriminatorFilter, (compEx, discValue) => discriminatorPredicates.Add(discValue, compEx)))
            {
                return(null);
            }

            var discriminatorProp    = (EdmProperty)((DbPropertyExpression)(discriminatorPredicates.First().Value).Left).Property;
            var rowConstructor       = (DbNewInstanceExpression)rowProjection.Projection;
            var resultRow            = TypeHelpers.GetEdmType <RowType>(rowConstructor.ResultType);
            var inputPredicateMap    = new Dictionary <string, DbComparisonExpression>();
            var selectorPredicateMap = new Dictionary <string, DbComparisonExpression>();
            var columnValues         = new Dictionary <string, DbExpression>(rowConstructor.Arguments.Count);

            for (var idx = 0; idx < rowConstructor.Arguments.Count; idx++)
            {
                var propName  = resultRow.Properties[idx].Name;
                var columnVal = rowConstructor.Arguments[idx];
                if (predicateColumnNames.Contains(propName))
                {
                    if (columnVal.ExpressionKind
                        != DbExpressionKind.Case)
                    {
                        return(null);
                    }
                    var 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)
                    {
                        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
            var newDiscriminatorPredicate = Helpers.BuildBalancedTreeInPlace(
                new List <DbExpression>(inputPredicateMap.Values), (left, right) => left.Or(right));

            discriminatorFilter = discriminatorFilter.Input.Filter(newDiscriminatorPredicate);

            var entitySelector = (DbCaseExpression)entityProjection.Projection;
            var newWhens       = new List <DbExpression>(entitySelector.When.Count);
            var newThens       = new List <DbExpression>(entitySelector.Then.Count);

            for (var idx = 0; idx < entitySelector.When.Count; idx++)
            {
                var propWhen   = (DbPropertyExpression)entitySelector.When[idx];
                var entityThen = (DbNewInstanceExpression)entitySelector.Then[idx];

                DbComparisonExpression discriminatorWhen;
                if (!selectorPredicateMap.TryGetValue(propWhen.Property.Name, out discriminatorWhen))
                {
                    return(null);
                }
                newWhens.Add(discriminatorWhen);

                var inputBoundEntityConstructor = ValueSubstituter.Substitute(entityThen, entityProjection.Input.VariableName, columnValues);
                newThens.Add(inputBoundEntityConstructor);
            }

            var newElse           = ValueSubstituter.Substitute(entitySelector.Else, entityProjection.Input.VariableName, columnValues);
            var newEntitySelector = DbExpressionBuilder.Case(newWhens, newThens, newElse);

            DbExpression result = discriminatorFilter.BindAs(rowProjection.Input.VariableName).Project(newEntitySelector);

            return(result);
        }
コード例 #11
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));
        }