예제 #1
0
        /// <summary>
        ///     This internal method ensures that the specified type is a scalar
        ///     type supported by the underlying provider by ensuring that scalar
        ///     metadata for this type is retrievable.
        /// </summary>
        internal bool ValidateParameterType(ClrPerspective perspective)
        {
            TypeUsage type;

            // The parameter type metadata is only valid if it's scalar or enumeration type metadata.
            if ((perspective.TryGetType(_mappableType, out type)) &&
                (TypeSemantics.IsScalarType(type)))
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        // <summary>
        // Constructs a EntityParameter from a CQT parameter.
        // </summary>
        private static EntityParameter CreateEntityParameterFromQueryParameter(KeyValuePair <string, TypeUsage> queryParameter)
        {
            // We really can't have a parameter here that isn't a scalar type...
            Debug.Assert(TypeSemantics.IsScalarType(queryParameter.Value), "Non-scalar type used as query parameter type");

            var result = new EntityParameter();

            result.ParameterName = queryParameter.Key;

            PopulateParameterFromTypeUsage(result, queryParameter.Value, isOutParam: false);

            return(result);
        }
예제 #3
0
        internal VarInfo CreatePrimitiveTypeVarInfo(Var v, Var newVar)
        {
            DebugCheck.NotNull(v);
            DebugCheck.NotNull(newVar);

            PlanCompiler.Assert(TypeSemantics.IsScalarType(v.Type), "The current variable should be of primitive or enum type.");
            PlanCompiler.Assert(TypeSemantics.IsScalarType(newVar.Type), "The new variable should be of primitive or enum type.");

            VarInfo varInfo = new PrimitiveTypeVarInfo(newVar);

            m_map.Add(v, varInfo);
            return(varInfo);
        }
        /// <summary>
        /// Determine whether the given CLR type is legal for an ObjectParameter or constant
        /// DbExpression.
        /// </summary>
        private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage)
        {
            EntityUtil.CheckArgumentNull(type, "type");

            if (_rootContext.Perspective.TryGetTypeByName(TypeSystem.GetNonNullableType(type).FullName,
                                                          false, // bIgnoreCase
                                                          out typeUsage) &&
                (TypeSemantics.IsScalarType(typeUsage)))
            {
                return(true);
            }

            typeUsage = null;
            return(false);
        }
예제 #5
0
        /// <summary>
        ///     Determine whether the given CLR type is legal for an ObjectParameter or constant
        ///     DbExpression.
        /// </summary>
        private bool TryGetTypeUsageForTerminal(Type type, out TypeUsage typeUsage)
        {
            DebugCheck.NotNull(type);

            if (_rootContext.Perspective.TryGetTypeByName(
                    TypeSystem.GetNonNullableType(type).FullNameWithNesting(),
                    false, // bIgnoreCase
                    out typeUsage)
                &&
                (TypeSemantics.IsScalarType(typeUsage)))
            {
                return(true);
            }

            typeUsage = null;
            return(false);
        }
예제 #6
0
        public FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            List <Tuple <StructuralType, List <StorageConditionPropertyMapping>, List <StoragePropertyMapping> > > structuralTypeMappings)
            : base(functionImport, targetFunction)
        {
            if (!functionImport.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("functionImport"));
            }

            if (!targetFunction.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("targetFunction"));
            }

            if (functionImport.EntitySet != null)
            {
                throw new NotSupportedException(Strings.ComposableFunctionImportsReturningEntitiesNotSupported);
            }

            EdmType resultType;

            if (!MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType))
            {
                throw new ArgumentException(Strings.InvalidReturnTypeForComposableFunction);
            }

            if (!TypeSemantics.IsScalarType(resultType) &&
                (structuralTypeMappings == null || structuralTypeMappings.Count == 0))
            {
                throw new ArgumentException(Strings.StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues);
            }

            m_structuralTypeMappings = structuralTypeMappings;
        }
예제 #7
0
        public override void Visit(DbConstantExpression e)
        {
            Debug.Assert(TypeSemantics.IsScalarType(e.ResultType), "Non-scalar type constant expressions are not supported.");
            var primitive = TypeHelpers.GetPrimitiveTypeUsageForScalar(e.ResultType);

            switch (((PrimitiveType)primitive.EdmType).PrimitiveTypeKind)
            {
            case PrimitiveTypeKind.Binary:
                var byteArray = e.Value as byte[];
                if (byteArray != null)
                {
                    _key.Append("'");
                    foreach (byte b in byteArray)
                    {
                        _key.AppendFormat("{0:X2}", b);
                    }
                    _key.Append("'");
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case PrimitiveTypeKind.String:
                var @string = e.Value as string;
                if (@string != null)
                {
                    _key.Append("'");
                    _key.Append(@string.Replace("'", "''"));
                    _key.Append("'");
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case PrimitiveTypeKind.Boolean:
            case PrimitiveTypeKind.Byte:
            case PrimitiveTypeKind.DateTime:
            case PrimitiveTypeKind.Decimal:
            case PrimitiveTypeKind.Double:
            case PrimitiveTypeKind.Guid:
            case PrimitiveTypeKind.Single:
            case PrimitiveTypeKind.SByte:
            case PrimitiveTypeKind.Int16:
            case PrimitiveTypeKind.Int32:
            case PrimitiveTypeKind.Int64:
            case PrimitiveTypeKind.Time:
            case PrimitiveTypeKind.DateTimeOffset:
                _key.AppendFormat(CultureInfo.InvariantCulture, "{0}", e.Value);
                break;

            case PrimitiveTypeKind.Geometry:
            case PrimitiveTypeKind.GeometryPoint:
            case PrimitiveTypeKind.GeometryLineString:
            case PrimitiveTypeKind.GeometryPolygon:
            case PrimitiveTypeKind.GeometryMultiPoint:
            case PrimitiveTypeKind.GeometryMultiLineString:
            case PrimitiveTypeKind.GeometryMultiPolygon:
            case PrimitiveTypeKind.GeometryCollection:
                var geometry = e.Value as DbGeometry;
                if (geometry != null)
                {
                    _key.Append(geometry.AsText());
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            case PrimitiveTypeKind.Geography:
            case PrimitiveTypeKind.GeographyPoint:
            case PrimitiveTypeKind.GeographyLineString:
            case PrimitiveTypeKind.GeographyPolygon:
            case PrimitiveTypeKind.GeographyMultiPoint:
            case PrimitiveTypeKind.GeographyMultiLineString:
            case PrimitiveTypeKind.GeographyMultiPolygon:
            case PrimitiveTypeKind.GeographyCollection:
                var geography = e.Value as DbGeography;
                if (geography != null)
                {
                    _key.Append(geography.AsText());
                }
                else
                {
                    throw new NotSupportedException();
                }
                break;

            default:
                throw new NotSupportedException();
            }

            _key.Append(":");
            _key.Append(e.ResultType.Identity);
        }
        /// <summary>
        /// Initializes a new FunctionImportMappingComposable instance.
        /// </summary>
        /// <param name="functionImport">The model function import.</param>
        /// <param name="targetFunction">The store composable function.</param>
        /// <param name="resultMapping">The result mapping for the function import.</param>
        /// <param name="containerMapping">The parent container mapping.</param>
        public FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            FunctionImportResultMapping resultMapping,
            EntityContainerMapping containerMapping)
            : base(
                Check.NotNull(functionImport, "functionImport"),
                Check.NotNull(targetFunction, "targetFunction"))
        {
            Check.NotNull(resultMapping, "resultMapping");
            Check.NotNull(containerMapping, "containerMapping");

            if (!functionImport.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("functionImport"));
            }

            if (!targetFunction.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("targetFunction"));
            }

            EdmType resultType;

            if (!MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType))
            {
                throw new ArgumentException(Strings.InvalidReturnTypeForComposableFunction);
            }

            // when this method is invoked when a CodeFirst model is being built (e.g. from a custom convention) the
            // StorageMappingItemCollection will be null. In this case we can call the converting method directly which
            // will return the correct result but the result won't be memoized. This however does not matter at this
            // point since the model is still being constructed.
            var cTypeTargetFunction =
                containerMapping.StorageMappingItemCollection != null
                ? containerMapping.StorageMappingItemCollection.StoreItemCollection.ConvertToCTypeFunction(targetFunction)
                : StoreItemCollection.ConvertFunctionSignatureToCType(targetFunction);

            var cTypeTvfElementType = TypeHelpers.GetTvfReturnType(cTypeTargetFunction);
            var sTypeTvfElementType = TypeHelpers.GetTvfReturnType(targetFunction);

            if (cTypeTvfElementType == null)
            {
                Debug.Assert(sTypeTvfElementType == null);

                throw new ArgumentException(
                          Strings.Mapping_FunctionImport_ResultMapping_InvalidSType(functionImport.Identity),
                          "functionImport");
            }

            var errors = new List <EdmSchemaError>();
            var functionImportHelper = new FunctionImportMappingComposableHelper(
                containerMapping,
                String.Empty,
                errors);

            FunctionImportMappingComposable mapping;

            if (Helper.IsStructuralType(resultType))
            {
                functionImportHelper.TryCreateFunctionImportMappingComposableWithStructuralResult(
                    functionImport,
                    cTypeTargetFunction,
                    resultMapping.SourceList,
                    cTypeTvfElementType,
                    sTypeTvfElementType,
                    LineInfo.Empty,
                    out mapping);
            }
            else
            {
                Debug.Assert(TypeSemantics.IsScalarType(resultType));
                Debug.Assert(resultMapping.TypeMappings.Count == 0);

                functionImportHelper.TryCreateFunctionImportMappingComposableWithScalarResult(
                    functionImport,
                    cTypeTargetFunction,
                    targetFunction,
                    resultType,
                    cTypeTvfElementType,
                    LineInfo.Empty,
                    out mapping);
            }

            if (mapping == null)
            {
                throw new InvalidOperationException(errors.Count > 0 ? errors[0].Message : String.Empty);
            }

            _containerMapping        = mapping._containerMapping;
            m_commandParameters      = mapping.m_commandParameters;
            m_structuralTypeMappings = mapping.m_structuralTypeMappings;
            m_targetFunctionKeys     = mapping.m_targetFunctionKeys;
            _resultMapping           = resultMapping;
        }
        internal FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            List <Tuple <StructuralType, List <ConditionPropertyMapping>, List <PropertyMapping> > > structuralTypeMappings,
            EdmProperty[] targetFunctionKeys,
            EntityContainerMapping containerMapping)
            : base(functionImport, targetFunction)
        {
            DebugCheck.NotNull(containerMapping);
            Debug.Assert(functionImport.IsComposableAttribute, "functionImport.IsComposableAttribute");
            Debug.Assert(targetFunction.IsComposableAttribute, "targetFunction.IsComposableAttribute");
            Debug.Assert(
                functionImport.EntitySet == null || structuralTypeMappings != null,
                "Function import returning entities must have structuralTypeMappings.");
            Debug.Assert(
                structuralTypeMappings == null || structuralTypeMappings.Count > 0, "Non-null structuralTypeMappings must not be empty.");
            EdmType resultType;

            Debug.Assert(
                structuralTypeMappings != null ||
                MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType) && TypeSemantics.IsScalarType(resultType),
                "Either type mappings should be specified or the function import should be Collection(Scalar).");
            Debug.Assert(
                functionImport.EntitySet == null || targetFunctionKeys != null,
                "Keys must be inferred for a function import returning entities.");
            Debug.Assert(targetFunctionKeys == null || targetFunctionKeys.Length > 0, "Keys must be null or non-empty.");

            _containerMapping = containerMapping;
            // We will use these parameters to target s-space function calls in the generated command tree.
            // Since enums don't exist in s-space we need to use the underlying type.
            m_commandParameters =
                functionImport.Parameters.Select(p => TypeHelpers.GetPrimitiveTypeUsageForScalar(p.TypeUsage).Parameter(p.Name)).ToArray();
            m_structuralTypeMappings = structuralTypeMappings;
            m_targetFunctionKeys     = targetFunctionKeys;
        }
        private bool TryGetTypeUsageForTerminal(Expression expression, out TypeUsage typeUsage)
        {
            Type type = expression.Type;

            if (this._rootContext.Perspective.TryGetTypeByName(TypeSystem.GetNonNullableType(type).FullNameWithNesting(), false, out typeUsage) && TypeSemantics.IsScalarType(typeUsage))
            {
                if (expression.NodeType == ExpressionType.Convert)
                {
                    type = ((UnaryExpression)expression).Operand.Type;
                }
                if (type.IsValueType && Nullable.GetUnderlyingType(type) == (Type)null && TypeSemantics.IsNullable(typeUsage))
                {
                    typeUsage = typeUsage.ShallowCopy(new FacetValues()
                    {
                        Nullable = (FacetValueContainer <bool?>) new bool?(false)
                    });
                }
                return(true);
            }
            typeUsage = (TypeUsage)null;
            return(false);
        }
예제 #11
0
 internal static bool IsValidInOpType(TypeUsage typeUsage)
 {
     return(TypeSemantics.IsReferenceType(typeUsage) ||
            TypeSemantics.IsEntityType(typeUsage) ||
            TypeSemantics.IsScalarType(typeUsage));
 }
        /// <summary>
        /// Initializes a new FunctionImportMappingComposable instance.
        /// </summary>
        /// <param name="functionImport">The model function import.</param>
        /// <param name="targetFunction">The store composable function.</param>
        /// <param name="resultMapping">The result mapping for the function import.</param>
        /// <param name="containerMapping">The parent container mapping.</param>
        public FunctionImportMappingComposable(
            EdmFunction functionImport,
            EdmFunction targetFunction,
            FunctionImportResultMapping resultMapping,
            EntityContainerMapping containerMapping)
            : base(
                Check.NotNull(functionImport, "functionImport"),
                Check.NotNull(targetFunction, "targetFunction"))
        {
            Check.NotNull(resultMapping, "resultMapping");
            Check.NotNull(containerMapping, "containerMapping");

            if (!functionImport.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("functionImport"));
            }

            if (!targetFunction.IsComposableAttribute)
            {
                throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("targetFunction"));
            }

            if (functionImport.EntitySet != null)
            {
                throw new NotSupportedException(Strings.ComposableFunctionImportsReturningEntitiesNotSupported);
            }

            EdmType resultType;

            if (!MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType))
            {
                throw new ArgumentException(Strings.InvalidReturnTypeForComposableFunction);
            }

            // Function mapping is allowed only for TVFs on the s-space.
            var cTypeTargetFunction = containerMapping.StorageMappingItemCollection.StoreItemCollection.ConvertToCTypeFunction(targetFunction);
            var cTypeTvfElementType = TypeHelpers.GetTvfReturnType(cTypeTargetFunction);
            var sTypeTvfElementType = TypeHelpers.GetTvfReturnType(targetFunction);

            if (cTypeTvfElementType == null)
            {
                Debug.Assert(sTypeTvfElementType == null);

                throw new ArgumentException(
                          Strings.Mapping_FunctionImport_ResultMapping_InvalidSType(functionImport.Identity),
                          "functionImport");
            }

            var errors = new List <EdmSchemaError>();
            var functionImportHelper = new FunctionImportMappingComposableHelper(
                containerMapping,
                String.Empty,
                errors);

            FunctionImportMappingComposable mapping;

            if (Helper.IsStructuralType(resultType))
            {
                functionImportHelper.TryCreateFunctionImportMappingComposableWithStructuralResult(
                    functionImport,
                    cTypeTargetFunction,
                    resultMapping.SourceList,
                    cTypeTvfElementType,
                    sTypeTvfElementType,
                    LineInfo.Empty,
                    out mapping);
            }
            else
            {
                Debug.Assert(TypeSemantics.IsScalarType(resultType));
                Debug.Assert(resultMapping.TypeMappings.Count == 0);

                functionImportHelper.TryCreateFunctionImportMappingComposableWithScalarResult(
                    functionImport,
                    cTypeTargetFunction,
                    targetFunction,
                    resultType,
                    cTypeTvfElementType,
                    LineInfo.Empty,
                    out mapping);
            }

            if (mapping == null)
            {
                throw new InvalidOperationException(errors.Count > 0 ? errors[0].Message : String.Empty);
            }

            _containerMapping        = mapping._containerMapping;
            m_commandParameters      = mapping.m_commandParameters;
            m_structuralTypeMappings = mapping.m_structuralTypeMappings;
            m_targetFunctionKeys     = mapping.m_targetFunctionKeys;
            _resultMapping           = resultMapping;
        }
 internal static bool IsValidIsNullOpType(TypeUsage typeUsage)
 {
     if (!TypeSemantics.IsReferenceType(typeUsage) && !TypeSemantics.IsEntityType(typeUsage) && !TypeSemantics.IsScalarType(typeUsage))
     {
         return(TypeSemantics.IsRowType(typeUsage));
     }
     return(true);
 }
예제 #14
0
        internal bool ValidateParameterType(ClrPerspective perspective)
        {
            TypeUsage outTypeUsage;

            return(perspective.TryGetType(this._mappableType, out outTypeUsage) && TypeSemantics.IsScalarType(outTypeUsage));
        }