Ejemplo n.º 1
0
 public override void Visit(RelPropertyOp op, Node n)
 {
     VisitScalarOpDefault(op, n);
     Assert(m_command.IsRelPropertyReferenced(op.PropertyInfo), "no such rel property:", op.PropertyInfo);
     Assert(
         TypeSemantics.IsEntityType(n.Child0.Op.Type), "argument to RelPropertyOp must be an entity type. Found: ", n.Child0.Op.Type);
 }
Ejemplo n.º 2
0
 // <summary>
 // Returns true if typeUsage type is valid for IS [NOT] NULL (expr) operator
 // </summary>
 internal static bool IsValidIsNullOpType(TypeUsage typeUsage)
 {
     return(TypeSemantics.IsReferenceType(typeUsage) ||
            TypeSemantics.IsEntityType(typeUsage) ||
            TypeSemantics.IsScalarType(typeUsage) ||
            TypeSemantics.IsRowType(typeUsage));
 }
Ejemplo n.º 3
0
        private ColumnMap CreateStructuralColumnMap(TypeUsage type, string name)
        {
            TypeInfo typeInfo = this.m_typeInfo.GetTypeInfo(type);

            if (TypeSemantics.IsRowType(type))
            {
                return((ColumnMap)this.CreateRecordColumnMap(typeInfo, name));
            }
            if (TypeSemantics.IsReferenceType(type))
            {
                return((ColumnMap)this.CreateRefColumnMap(typeInfo, name));
            }
            if (typeInfo.HasTypeIdProperty)
            {
                return((ColumnMap)this.CreatePolymorphicColumnMap(typeInfo, name));
            }
            if (TypeSemantics.IsComplexType(type))
            {
                return((ColumnMap)this.CreateComplexTypeColumnMap(typeInfo, name, (ComplexTypeColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null));
            }
            if (TypeSemantics.IsEntityType(type))
            {
                return((ColumnMap)this.CreateEntityColumnMap(typeInfo, name, (EntityColumnMap)null, (Dictionary <object, TypedColumnMap>)null, (List <TypedColumnMap>)null, true));
            }
            throw new NotSupportedException(type.Identity);
        }
Ejemplo n.º 4
0
 private void ExplodeRootStructuredType(RootTypeInfo rootType)
 {
     if (rootType.FlattenedType != null)
     {
         return;
     }
     if (StructuredTypeInfo.NeedsTypeIdProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)TypeIdPropertyRef.Instance);
         if (rootType.DiscriminatorMap != null)
         {
             rootType.TypeIdKind = TypeIdKind.UserSpecified;
             rootType.TypeIdType = Helper.GetModelTypeUsage(rootType.DiscriminatorMap.DiscriminatorProperty);
         }
         else
         {
             rootType.TypeIdKind = TypeIdKind.Generated;
             rootType.TypeIdType = this.m_stringType;
         }
     }
     if (this.NeedsEntitySetIdProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)EntitySetIdPropertyRef.Instance);
     }
     if (this.NeedsNullSentinelProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)NullSentinelPropertyRef.Instance);
     }
     this.ExplodeRootStructuredTypeHelper((TypeInfo)rootType);
     if (TypeSemantics.IsEntityType(rootType.Type))
     {
         this.AddRelProperties((TypeInfo)rootType);
     }
     this.CreateFlattenedRecordType(rootType);
 }
Ejemplo n.º 5
0
            internal static DbExpression FindNavigationExpression(DbExpression expression, AliasGenerator aliasGenerator, out NavigationInfo navInfo)
            {
                Debug.Assert(TypeSemantics.IsCollectionType(expression.ResultType), "Non-collection input to projection?");

                navInfo = null;

                TypeUsage elementType = ((CollectionType)expression.ResultType.EdmType).TypeUsage;

                if (!TypeSemantics.IsEntityType(elementType) && !TypeSemantics.IsReferenceType(elementType))
                {
                    return(expression);
                }

                RelationshipNavigationVisitor visitor = new RelationshipNavigationVisitor(aliasGenerator);
                DbExpression rewrittenExpression      = visitor.Find(expression);

                if (!object.ReferenceEquals(expression, rewrittenExpression))
                {
                    Debug.Assert(visitor._original != null && visitor._rewritten != null, "Expression was rewritten but no navigation was found?");
                    navInfo = new NavigationInfo(visitor._original, visitor._rewritten);
                    return(rewrittenExpression);
                }
                else
                {
                    return(expression);
                }
            }
 internal static bool IsValidInOpType(TypeUsage typeUsage)
 {
     if (!TypeSemantics.IsReferenceType(typeUsage) && !TypeSemantics.IsEntityType(typeUsage))
     {
         return(TypeSemantics.IsScalarType(typeUsage));
     }
     return(true);
 }
Ejemplo n.º 7
0
        internal DbNewInstanceExpression(TypeUsage resultType, DbExpressionList attributeValues, System.Collections.ObjectModel.ReadOnlyCollection <DbRelatedEntityRef> relationships)
            : this(resultType, attributeValues)
        {
            Debug.Assert(TypeSemantics.IsEntityType(resultType), "An entity type is required to create a NewEntityWithRelationships expression");
            Debug.Assert(relationships != null, "Related entity ref collection cannot be null");

            this._relatedEntityRefs = (relationships.Count > 0 ? relationships : null);
        }
Ejemplo n.º 8
0
        public override void Visit(DerefOp op, Node n)
        {
            VisitScalarOpDefault(op, n);
            Assert(TypeSemantics.IsEntityType(op.Type), "Expected an entity type. Found " + op.Type);
            Assert(TypeSemantics.IsReferenceType(n.Child0.Op.Type), "Expected a ref type. Found " + n.Child0.Op.Type);
            RefType r = n.Child0.Op.Type.EdmType as RefType;

            Assert(r.ElementType.EdmEquals(op.Type.EdmType), "Inconsistent types");
        }
Ejemplo n.º 9
0
        internal DbNewInstanceExpression(
            TypeUsage resultType, DbExpressionList attributeValues, ReadOnlyCollection <DbRelatedEntityRef> relationships)
            : this(resultType, attributeValues)
        {
            Debug.Assert(
                TypeSemantics.IsEntityType(resultType), "An entity type is required to create a NewEntityWithRelationships expression");
            DebugCheck.NotNull(relationships);

            _relatedEntityRefs = (relationships.Count > 0 ? relationships : null);
        }
Ejemplo n.º 10
0
        private void AssignTypeIds()
        {
            int num = 0;

            foreach (KeyValuePair <TypeUsage, TypeInfo> typeInfo in this.m_typeInfoMap)
            {
                if (typeInfo.Value.RootType.DiscriminatorMap != null)
                {
                    EntityType edmType = (EntityType)typeInfo.Key.EdmType;
                    typeInfo.Value.TypeId = typeInfo.Value.RootType.DiscriminatorMap.GetTypeId(edmType);
                }
                else if (typeInfo.Value.IsRootType && (TypeSemantics.IsEntityType(typeInfo.Key) || TypeSemantics.IsComplexType(typeInfo.Key)))
                {
                    this.AssignRootTypeId(typeInfo.Value, string.Format((IFormatProvider)CultureInfo.InvariantCulture, "{0}X", (object)num));
                    ++num;
                }
            }
        }
Ejemplo n.º 11
0
        private void CreateFlattenedRecordType(RootTypeInfo type)
        {
            bool flag = TypeSemantics.IsEntityType(type.Type) && type.ImmediateSubTypes.Count == 0;
            List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >();
            HashSet <string> stringSet = new HashSet <string>();
            int num = 0;

            foreach (PropertyRef propertyRef in type.PropertyRefList)
            {
                string key = (string)null;
                if (flag)
                {
                    SimplePropertyRef simplePropertyRef = propertyRef as SimplePropertyRef;
                    if (simplePropertyRef != null)
                    {
                        key = simplePropertyRef.Property.Name;
                    }
                }
                if (key == null)
                {
                    key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture);
                    ++num;
                }
                while (stringSet.Contains(key))
                {
                    key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture);
                    ++num;
                }
                TypeUsage propertyType = this.GetPropertyType(type, propertyRef);
                keyValuePairList.Add(new KeyValuePair <string, TypeUsage>(key, propertyType));
                stringSet.Add(key);
            }
            type.FlattenedType = TypeHelpers.CreateRowType((IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList);
            IEnumerator <PropertyRef> enumerator = type.PropertyRefList.GetEnumerator();

            foreach (EdmProperty property in type.FlattenedType.Properties)
            {
                if (!enumerator.MoveNext())
                {
                    System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?");
                }
                type.AddPropertyMapping(enumerator.Current, property);
            }
        }
            internal static DbExpression FindNavigationExpression(
                DbExpression expression,
                AliasGenerator aliasGenerator,
                out ObjectSpanRewriter.NavigationInfo navInfo)
            {
                navInfo = (ObjectSpanRewriter.NavigationInfo)null;
                TypeUsage typeUsage = ((CollectionType)expression.ResultType.EdmType).TypeUsage;

                if (!TypeSemantics.IsEntityType(typeUsage) && !TypeSemantics.IsReferenceType(typeUsage))
                {
                    return(expression);
                }
                ObjectSpanRewriter.RelationshipNavigationVisitor navigationVisitor = new ObjectSpanRewriter.RelationshipNavigationVisitor(aliasGenerator);
                DbExpression dbExpression = navigationVisitor.Find(expression);

                if (object.ReferenceEquals((object)expression, (object)dbExpression))
                {
                    return(expression);
                }
                navInfo = new ObjectSpanRewriter.NavigationInfo(navigationVisitor._original, navigationVisitor._rewritten);
                return(dbExpression);
            }
Ejemplo n.º 13
0
        public override void Visit(ComparisonOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
        {
            TypeUsage type = (n.Child0.Op as ScalarOp).Type;

            if (!TypeUtils.IsStructuredType(type))
            {
                this.VisitChildren(n);
            }
            else if (TypeSemantics.IsRowType(type) || TypeSemantics.IsReferenceType(type))
            {
                this.VisitDefault(n);
            }
            else
            {
                System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeSemantics.IsEntityType(type), "unexpected childOpType?");
                PropertyRefList identityProperties = PropertyPushdownHelper.GetIdentityProperties(TypeHelpers.GetEdmType <EntityType>(type));
                foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Children)
                {
                    this.AddPropertyRefs(child, identityProperties);
                }
                this.VisitChildren(n);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Adds the flattened properties on the input to the flattenedProperties list.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="flattenedProperties"></param>
        private void FlattenProperties(DbExpression input, IList <DbPropertyExpression> flattenedProperties)
        {
            IList <EdmProperty> properties = TypeHelpers.GetProperties(input.ResultType);

            Debug.Assert(properties.Count != 0, "No nested properties when FlattenProperties called?");

            for (int i = 0; i < properties.Count; i++)
            {
                DbExpression propertyInput = input;

                DbPropertyExpression propertyExpression = propertyInput.Property(properties[i]);
                if (TypeSemantics.IsPrimitiveType(properties[i].TypeUsage))
                {
                    flattenedProperties.Add(propertyExpression);
                }
                else
                {
                    Debug.Assert(TypeSemantics.IsEntityType(properties[i].TypeUsage) || TypeSemantics.IsRowType(properties[i].TypeUsage),
                                 "The input to FlattenProperties is not of EntityType or RowType?");

                    FlattenProperties(propertyExpression, flattenedProperties);
                }
            }
        }
Ejemplo n.º 15
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));
        }
Ejemplo n.º 16
0
 internal DbDerefExpression(TypeUsage entityResultType, DbExpression refExpr)
     : base(DbExpressionKind.Deref, entityResultType, refExpr)
 {
     Debug.Assert(TypeSemantics.IsEntityType(entityResultType), "DbDerefExpression requires an entity result type");
 }
Ejemplo n.º 17
0
 internal static bool IsStructuredType(TypeUsage type)
 {
     if (!TypeSemantics.IsReferenceType(type) && !TypeSemantics.IsRowType(type) && (!TypeSemantics.IsEntityType(type) && !TypeSemantics.IsRelationshipType(type)))
     {
         return(TypeSemantics.IsComplexType(type));
     }
     return(true);
 }
Ejemplo n.º 18
0
 internal NewInstanceOp(TypeUsage type)
     : base(OpType.NewInstance, type)
 {
     Debug.Assert(!type.EdmType.Abstract, "cannot create new instance of abstract type");
     Debug.Assert(!TypeSemantics.IsEntityType(type), "cannot use this Op for entity construction");
 }
Ejemplo n.º 19
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);
        }