/// <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); }
// <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); }
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); }
/// <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); }
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; }
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); }
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); }
internal bool ValidateParameterType(ClrPerspective perspective) { TypeUsage outTypeUsage; return(perspective.TryGetType(this._mappableType, out outTypeUsage) && TypeSemantics.IsScalarType(outTypeUsage)); }