private void AppendType(EdmProperty column, bool isMigrationHistoryPrimaryKey) { Facet storeGenFacet; var type = column.TypeUsage; if (isMigrationHistoryPrimaryKey) { type = TypeUsage.CreateStringTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, false, VfpClient.VfpMapping.MaximumCharacterFieldSizeThatCanBeIndex); } AppendIdentifier(SqlVisitor.GetSqlPrimitiveType(type)); AppendSql(column.Nullable ? " null" : " not null"); if (!column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out storeGenFacet) || storeGenFacet.Value == null) { return; } var storeGenPattern = (StoreGeneratedPattern)storeGenFacet.Value; if (storeGenPattern == StoreGeneratedPattern.Identity) { AppendSql(" autoinc"); } }
private static EntityType CreateEntityTypeWithExtendedProperty(XNamespace copyToSSDLNamespace, string copyToSSDLValue) { var extendedPropertyContents = new XElement( (XNamespace)"http://myExtendedProperties" + "MyProp", new XAttribute( (XNamespace)"http://myExtendedProperties" + "MyAttribute", "MyValue"), new XAttribute( copyToSSDLNamespace + "CopyToSSDL", copyToSSDLValue)); var extendedPropertyMetadataProperty = MetadataProperty.Create( "http://myExtendedProperties:MyProp", TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), true, false), extendedPropertyContents ); return(EntityType.Create( "TestEntityType", "Model1", DataSpace.CSpace, new[] { "Id" }, new[] { EdmProperty.CreatePrimitive("Id", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String)) }, new[] { extendedPropertyMetadataProperty })); }
public void ForceNonUnicode_converts_a_unicode_string_type_usage_to_a_non_unicode_string_type_usage() { var stringUsage = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), isUnicode: true, isFixedLength: false, maxLength: 256); var facets = stringUsage.Facets.Select( f => new { f.Name, f.Value }).ToList(); var nonUnicode = stringUsage.ForceNonUnicode(); Assert.False((bool)nonUnicode.Facets.Single(f => f.Name == "Unicode").Value); foreach (var facet in facets) { if (facet.Name != "Unicode") { Assert.Equal(facet.Value, nonUnicode.Facets.Single(f => f.Name == facet.Name).Value); } } }
private static TypeUsage GetTypeUsage(EdmType edmType, SimpleTypeDescriptor simpleTypeDescriptor) { if (edmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) { PrimitiveType primitiveType = (PrimitiveType)edmType; switch (primitiveType.PrimitiveTypeKind) { case PrimitiveTypeKind.Binary: return(simpleTypeDescriptor.Length.HasValue && simpleTypeDescriptor.Length.Value >= 0 ? TypeUsage.CreateBinaryTypeUsage(primitiveType, simpleTypeDescriptor.IsFixedLength.HasValue && simpleTypeDescriptor.IsFixedLength.Value, simpleTypeDescriptor.Length.Value) : simpleTypeDescriptor.IsFixedLength.HasValue?TypeUsage.CreateBinaryTypeUsage(primitiveType, simpleTypeDescriptor.IsFixedLength.Value) : TypeUsage.CreateDefaultTypeUsage(primitiveType)); case PrimitiveTypeKind.String: return(simpleTypeDescriptor.Length.HasValue && simpleTypeDescriptor.Length.Value >= 0 ? TypeUsage.CreateStringTypeUsage(primitiveType, true, simpleTypeDescriptor.IsFixedLength.HasValue && simpleTypeDescriptor.IsFixedLength.Value, simpleTypeDescriptor.Length.Value) : simpleTypeDescriptor.IsFixedLength.HasValue?TypeUsage.CreateStringTypeUsage(primitiveType, true, simpleTypeDescriptor.IsFixedLength.Value) : TypeUsage.CreateDefaultTypeUsage(primitiveType)); case PrimitiveTypeKind.Decimal: return(simpleTypeDescriptor.Precision.HasValue && simpleTypeDescriptor.Scale.HasValue ? TypeUsage.CreateDecimalTypeUsage(primitiveType, simpleTypeDescriptor.Precision.Value, simpleTypeDescriptor.Scale.Value) : TypeUsage.CreateDefaultTypeUsage(primitiveType)); case PrimitiveTypeKind.DateTimeOffset: return(TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, simpleTypeDescriptor.Precision)); case PrimitiveTypeKind.Time: return(TypeUsage.CreateTimeTypeUsage(primitiveType, simpleTypeDescriptor.Precision)); } } return(TypeUsage.CreateDefaultTypeUsage(edmType)); }
public void GetEdmType_returns_correct_type_usages_for_specific_String_type_usages() { foreach (var isUnicode in new[] { true, false }) { foreach (var isFixedLength in new[] { true, false }) { TypeUsageVerificationHelper.VerifyTypeUsagesEquivalent( LegacyProviderManifest.GetEdmType( LegacyProviderManifest.GetStoreType( LegacyMetadata.TypeUsage.CreateStringTypeUsage(LegacyEdmPrimitiveTypes["String"], isUnicode, isFixedLength))), ProviderManifestWrapper.GetEdmType( ProviderManifestWrapper.GetStoreType( TypeUsage.CreateStringTypeUsage(EdmPrimitiveTypes["String"], isUnicode, isFixedLength)))); TypeUsageVerificationHelper.VerifyTypeUsagesEquivalent( LegacyProviderManifest.GetEdmType( LegacyProviderManifest.GetStoreType( LegacyMetadata.TypeUsage.CreateStringTypeUsage( LegacyEdmPrimitiveTypes["String"], isUnicode, isFixedLength, maxLength: 1000))), ProviderManifestWrapper.GetEdmType( ProviderManifestWrapper.GetStoreType( TypeUsage.CreateStringTypeUsage(EdmPrimitiveTypes["String"], isUnicode, isFixedLength, maxLength: 1000)))); } } }
public void SimpleTypeShouldBeEscaped() { var edmType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String); var typeUsage = TypeUsage.CreateStringTypeUsage(edmType, false, false); this.escaper.Escape(typeUsage).Should().Be("global::System.String"); }
private TypeUsage CreateStringTypeUsage(PrimitiveType edmPrimitiveType, bool isUnicode, bool isFixedLen, int?maxLength = null) { if (maxLength == null) { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, isUnicode, isFixedLen)); } return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, isUnicode, isFixedLen, maxLength.Value)); }
/// <summary> /// Determines the expected shape of store results. We expect a column for every property /// of the mapped type (or types) and a column for every discriminator column. We make no /// assumptions about the order of columns: the provider is expected to determine appropriate /// types by looking at the names of the result columns, not the order of columns, which is /// different from the typical handling of row types in the EF. /// </summary> /// <remarks> /// Requires that the given function import mapping refers to a Collection(Entity) or Collection(ComplexType) CSDL /// function. /// </remarks> /// <returns>Row type.</returns> internal TypeUsage GetExpectedTargetResultType(MetadataWorkspace workspace, int resultSetIndex) { FunctionImportStructuralTypeMappingKB resultMapping = this.GetResultMapping(resultSetIndex); // Collect all columns as name-type pairs. Dictionary <string, TypeUsage> columns = new Dictionary <string, TypeUsage>(); // Figure out which entity types we expect to yield from the function. IEnumerable <StructuralType> structuralTypes; if (0 == resultMapping.NormalizedEntityTypeMappings.Count) { // No explicit type mappings; just use the type specified in the ReturnType attribute on the function. StructuralType structuralType; MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(this.FunctionImport, resultSetIndex, out structuralType); Debug.Assert(null != structuralType, "this method must be called only for entity/complextype reader function imports"); structuralTypes = new StructuralType[] { structuralType }; } else { // Types are explicitly mapped. structuralTypes = resultMapping.MappedEntityTypes.Cast <StructuralType>(); } // Gather columns corresponding to all properties. foreach (StructuralType structuralType in structuralTypes) { foreach (EdmProperty property in TypeHelpers.GetAllStructuralMembers(structuralType)) { // NOTE: if a complex type is encountered, the column map generator will // throw. For now, we just let them through. // We expect to see each property multiple times, so we use indexer rather than // .Add. columns[property.Name] = property.TypeUsage; } } // Gather discriminator columns. foreach (string discriminatorColumn in this.GetDiscriminatorColumns(resultSetIndex)) { if (!columns.ContainsKey(discriminatorColumn)) { // TypeUsage type = TypeUsage.CreateStringTypeUsage(workspace.GetModelPrimitiveType(PrimitiveTypeKind.String), true, false); columns.Add(discriminatorColumn, type); } } // Expected type is a collection of rows RowType rowType = new RowType(columns.Select(c => new EdmProperty(c.Key, c.Value))); TypeUsage result = TypeUsage.Create(new CollectionType(TypeUsage.Create(rowType))); return(result); }
/// <summary> /// Creates a SQLiteParameter given a name, type, and direction /// </summary> internal static SQLiteParameter CreateSqlParameter(SQLiteProviderManifest manifest, string name, TypeUsage type, ParameterMode mode, object value) { int?size; // // NOTE: Adjust the parameter type so that it will work with textual // GUIDs. Please see ticket [a4d9c7ee94] for more details. // if ((manifest != null) && !manifest._binaryGuid && (MetadataHelpers.GetPrimitiveTypeKind(type) == PrimitiveTypeKind.Guid)) { type = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, true); } SQLiteParameter result = new SQLiteParameter(name, value); // .Direction ParameterDirection direction = MetadataHelpers.ParameterModeToParameterDirection(mode); if (result.Direction != direction) { result.Direction = direction; } // .Size and .DbType // output parameters are handled differently (we need to ensure there is space for return // values where the user has not given a specific Size/MaxLength) bool isOutParam = mode != ParameterMode.In; DbType sqlDbType = GetSqlDbType(type, isOutParam, out size); if (result.DbType != sqlDbType) { result.DbType = sqlDbType; } // Note that we overwrite 'facet' parameters where either the value is different or // there is an output parameter. if (size.HasValue && (isOutParam || result.Size != size.Value)) { result.Size = size.Value; } // .IsNullable bool isNullable = MetadataHelpers.IsNullable(type); if (isOutParam || isNullable != result.IsNullable) { result.IsNullable = isNullable; } return(result); }
public void SetDbParameterValue_invokes_SetParameterValue_on_wrapped_provider() { var mockProviderServices = new Mock <DbProviderServices>(); var typeUsage = TypeUsage.CreateStringTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), true, false); new CachingProviderServices(mockProviderServices.Object, new Mock <CacheTransactionHandler>(Mock.Of <ICache>()).Object) .SetParameterValue(Mock.Of <DbParameter>(), typeUsage, "abc"); mockProviderServices .Protected() .Verify("SetDbParameterValue", Times.Once(), ItExpr.IsAny <DbParameter>(), typeUsage, "abc"); }
internal static TypeUsage CopyTypeUsageAndSetUnicodeFacetToFalse(TypeUsage typeUsage) { bool isFixedLength = false; int maxLength = 0; EF6MetadataHelpers.TryGetIsFixedLength(typeUsage, out isFixedLength); EF6MetadataHelpers.TryGetMaxLength(typeUsage, out maxLength); if (maxLength > 0) { return(TypeUsage.CreateStringTypeUsage((PrimitiveType)typeUsage.EdmType, false, isFixedLength, maxLength)); } return(TypeUsage.CreateStringTypeUsage((PrimitiveType)typeUsage.EdmType, false, isFixedLength)); }
public EdmProperty BuildString(string name, bool isUnicode, bool isFixedLength) { var typeUsage = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), isUnicode, isFixedLength); var property = EdmProperty.Create( name, typeUsage); return(property); }
/// <summary> /// Creates a SQLiteParameter given a name, type, and direction /// </summary> internal static SQLiteParameter CreateSQLiteParameter(string name, TypeUsage type, ParameterMode mode, object value) { int?size; if (type.GetPrimitiveTypeKind() == PrimitiveTypeKind.Guid) { type = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, true); } var result = new SQLiteParameter(name, value); // .Direction var direction = MetadataHelpers.ParameterModeToParameterDirection(mode); if (result.Direction != direction) { result.Direction = direction; } // .Size and .DbType // output parameters are handled differently (we need to ensure there is space for return // values where the user has not given a specific Size/MaxLength) var isOutParam = mode != ParameterMode.In; var sqlDbType = GetSQLiteDbType(type, isOutParam, out size); if (result.DbType != sqlDbType) { result.DbType = sqlDbType; } // Note that we overwrite 'facet' parameters where either the value is different or // there is an output parameter. if (size.HasValue && (isOutParam || result.Size != size.Value)) { result.Size = size.Value; } // .IsNullable var isNullable = type.GetIsNullable(); if (isOutParam || isNullable != result.IsNullable) { result.IsNullable = isNullable; } return(result); }
public override TypeUsage GetEdmType(TypeUsage storeType) { string storeTypeName = storeType.EdmType.Name.ToLower(); PrimitiveType edmPrimitiveType = base.StoreTypeNameToEdmPrimitiveType[storeTypeName]; if (storeTypeName == "string" || storeTypeName == "varchar") { Facet f; int maxLength = -1; if (storeType.Facets.TryGetValue("MaxLength", false, out f) && !f.IsUnbounded && f.Value != null) { maxLength = (int)f.Value; } if (maxLength != -1) { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false, maxLength)); } else { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false)); } } else if (storeTypeName == "decimal" || storeTypeName == "numeric") { Facet f; byte precision = 0; if (storeType.Facets.TryGetValue("Precision", false, out f) && !f.IsUnbounded && f.Value != null) { precision = (byte)f.Value; } byte scale = 0; if (storeType.Facets.TryGetValue("Scale", false, out f) && !f.IsUnbounded && f.Value != null) { scale = (byte)f.Value; } if (precision != 0 && scale != 0) { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType, precision, scale)); } else { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType)); } } else { return(TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType)); } throw new NotImplementedException(); }
private static MetadataProperty CreateAnnotationMetadataProperty(string name, string value) { return (MetadataProperty.Create( string.Format( CultureInfo.InvariantCulture, "{0}:{1}", SchemaManager.AnnotationNamespace, name), TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), isUnicode: false, isFixedLength: false), value)); }
internal static TypeUsage ForceNonUnicode(this TypeUsage typeUsage) { // Obtain a non-unicode facet var nonUnicodeString = TypeUsage.CreateStringTypeUsage( (PrimitiveType)typeUsage.EdmType, isUnicode: false, isFixedLength: false); // Copy all existing facets except replace the non-unicode facet return(TypeUsage.Create( typeUsage.EdmType, typeUsage.Facets .Where(f => f.Name != DbProviderManifest.UnicodeFacetName) .Union( nonUnicodeString.Facets.Where(f => f.Name == DbProviderManifest.UnicodeFacetName)))); }
public static void VisitDbIsNullExpression_non_parameter_reference_expression_is_not_cast() { var primitiveType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String); var typeUsage = TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode: true, isFixedLength: false); var isNullExpression = typeUsage.Constant("constant").IsNull(); var sqlGenerator = new SqlGenerator(); var sqlFragment = sqlGenerator.Visit(isNullExpression); var builder = new StringBuilder(); using (var writer = new SqlWriter(builder)) { sqlFragment.WriteSql(writer, sqlGenerator); } Assert.Equal("N'constant' IS NULL", builder.ToString()); }
public static void VisitDbIsNullExpression_variable_size_string_parameter_with_max_length_is_not_cast() { var primitiveType = PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String); var typeUsage = TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode: true, isFixedLength: false, maxLength: 100); var isNullExpression = typeUsage.Parameter("parameterName").IsNull(); var sqlGenerator = new SqlGenerator(); var sqlFragment = sqlGenerator.Visit(isNullExpression); var builder = new StringBuilder(); using (var writer = new SqlWriter(builder)) { sqlFragment.WriteSql(writer, sqlGenerator); } Assert.Equal("@parameterName IS NULL", builder.ToString()); }
private static EdmProperty CreateColumn( Mock <EntityType> mockTableType, string name, Properties.Primitive.PrimitivePropertyConfiguration config = null) { var mockColumn = CreateMockMember(mockTableType.Object, name); mockColumn.Setup(m => m.Annotations).Returns( config == null ? new MetadataProperty[0] : new[] { MetadataProperty.CreateAnnotation("Configuration", config) }); mockColumn.SetupProperty( m => m.TypeUsage, TypeUsage.CreateStringTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), true, false)); mockTableType.Setup(m => m.HasMember(mockColumn.Object)).Returns(true); return(mockColumn.Object); }
public void Visit_DbConstantExpression_creates_equivalent_legacy_DbConstantExpression() { var typeUsage = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), isUnicode: false, isFixedLength: true, maxLength: 1000); var constantExpression = typeUsage.Constant("test"); var legacyConstantExpression = _legacyDbExpressionConverter.Visit(constantExpression) as LegacyCommandTrees.DbConstantExpression; Assert.NotNull(legacyConstantExpression); Assert.Equal(LegacyCommandTrees.DbExpressionKind.Constant, legacyConstantExpression.ExpressionKind); Assert.Equal(constantExpression.Value, legacyConstantExpression.Value); TypeUsageVerificationHelper .VerifyTypeUsagesEquivalent(legacyConstantExpression.ResultType, constantExpression.ResultType); }
public void TestingMaxLengthFacet() { using (MySqlConnection connection = new MySqlConnection(st.GetConnectionString(true))) { MySqlProviderManifest pm = new MySqlProviderManifest(st.Version.ToString()); TypeUsage tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, false); TypeUsage result = pm.GetStoreType(tu); Assert.Equal("longtext", result.EdmType.Name); tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, false, Int32.MaxValue); result = pm.GetStoreType(tu); Assert.Equal("longtext", result.EdmType.Name); tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, false, 70000); result = pm.GetStoreType(tu); Assert.Equal("mediumtext", result.EdmType.Name); } }
public void TestingMaxLengthWithFixedLenghtTrueFacets() { using (MySqlConnection connection = new MySqlConnection(st.ConnectionString)) { MySqlProviderManifest pm = new MySqlProviderManifest(st.Version.ToString()); TypeUsage tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, true); TypeUsage result = pm.GetStoreType(tu); Assert.Equal("char", result.EdmType.Name); tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, true, Int32.MaxValue); result = pm.GetStoreType(tu); Assert.Equal("char", result.EdmType.Name); tu = TypeUsage.CreateStringTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), false, true, 70000); result = pm.GetStoreType(tu); Assert.Equal("char", result.EdmType.Name); } }
public override TypeUsage GetEdmType(TypeUsage storeType) { string storeTypeName = storeType.EdmType.Name.ToLower(); PrimitiveType edmPrimitiveType = base.StoreTypeNameToEdmPrimitiveType[storeTypeName]; if (storeTypeName == "string" || storeTypeName == "varchar") { Facet fMaxLength = null; storeType.Facets.TryGetValue("MaxLength", false, out fMaxLength); if (fMaxLength != null && !fMaxLength.IsUnbounded && fMaxLength.Value != null) { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false, (int)fMaxLength.Value)); } else { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false)); } } else if (storeTypeName == "decimal" || storeTypeName == "numeric") { Facet fPrecision = null; storeType.Facets.TryGetValue("Precision", false, out fPrecision); Facet fScale = null; storeType.Facets.TryGetValue("Scale", false, out fScale); if (fPrecision != null && !fPrecision.IsUnbounded && fPrecision.Value != null && fScale != null && !fScale.IsUnbounded && fScale.Value != null) { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType, (byte)fPrecision.Value, (byte)fScale.Value)); } else { return(TypeUsage.CreateDecimalTypeUsage(edmPrimitiveType)); } } else { return(TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType)); } throw new NotImplementedException(); }
public override TypeUsage GetEdmType(TypeUsage storeType) { if (storeType == null) { throw new ArgumentNullException("storeType"); } string storeTypeName = storeType.EdmType.Name.ToLowerInvariant(); if (!base.StoreTypeNameToEdmPrimitiveType.ContainsKey(storeTypeName)) { throw new ArgumentException(String.Format("The underlying provider does not support the type '{0}'.", storeTypeName)); } PrimitiveType edmPrimitiveType = base.StoreTypeNameToEdmPrimitiveType[storeTypeName]; if (edmPrimitiveType.PrimitiveTypeKind == PrimitiveTypeKind.Binary) { return(TypeUsage.CreateBinaryTypeUsage(edmPrimitiveType, false)); } if (edmPrimitiveType.PrimitiveTypeKind == PrimitiveTypeKind.String) { Facet facet; if (storeType.Facets.TryGetValue("MaxLength", false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false, (int)facet.Value)); } else { return(TypeUsage.CreateStringTypeUsage(edmPrimitiveType, false, false)); } } return(TypeUsage.CreateDefaultTypeUsage(edmPrimitiveType)); }
internal TypeUsage GetExpectedTargetResultType(int resultSetIndex) { FunctionImportStructuralTypeMappingKB resultMapping = this.GetResultMapping(resultSetIndex); Dictionary <string, TypeUsage> source = new Dictionary <string, TypeUsage>(); IEnumerable <StructuralType> structuralTypes; if (resultMapping.NormalizedEntityTypeMappings.Count == 0) { StructuralType returnType; MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(this.FunctionImport, resultSetIndex, out returnType); structuralTypes = (IEnumerable <StructuralType>) new StructuralType[1] { returnType }; } else { structuralTypes = resultMapping.MappedEntityTypes.Cast <StructuralType>(); } foreach (EdmType edmType in structuralTypes) { foreach (EdmProperty structuralMember in (IEnumerable)TypeHelpers.GetAllStructuralMembers(edmType)) { source[structuralMember.Name] = structuralMember.TypeUsage; } } foreach (string discriminatorColumn in (IEnumerable <string>) this.GetDiscriminatorColumns(resultSetIndex)) { if (!source.ContainsKey(discriminatorColumn)) { TypeUsage stringTypeUsage = TypeUsage.CreateStringTypeUsage(MetadataWorkspace.GetModelPrimitiveType(PrimitiveTypeKind.String), true, false); source.Add(discriminatorColumn, stringTypeUsage); } } return(TypeUsage.Create((EdmType) new CollectionType(TypeUsage.Create((EdmType) new RowType(source.Select <KeyValuePair <string, TypeUsage>, EdmProperty>((Func <KeyValuePair <string, TypeUsage>, EdmProperty>)(c => new EdmProperty(c.Key, c.Value)))))))); }
// <summary> // Determines the expected shape of store results. We expect a column for every property // of the mapped type (or types) and a column for every discriminator column. We make no // assumptions about the order of columns: the provider is expected to determine appropriate // types by looking at the names of the result columns, not the order of columns, which is // different from the typical handling of row types in the EF. // </summary> // <remarks> // Requires that the given function import mapping refers to a Collection(Entity) or Collection(ComplexType) CSDL // function. // </remarks> // <returns> Row type. </returns> internal TypeUsage GetExpectedTargetResultType(int resultSetIndex) { var resultMapping = GetResultMapping(resultSetIndex); // Collect all columns as name-type pairs. var columns = new Dictionary <string, TypeUsage>(); // Figure out which entity types we expect to yield from the function. IEnumerable <StructuralType> structuralTypes; if (0 == resultMapping.NormalizedEntityTypeMappings.Count) { // No explicit type mappings; just use the type specified in the ReturnType attribute on the function. StructuralType structuralType; MetadataHelper.TryGetFunctionImportReturnType(FunctionImport, resultSetIndex, out structuralType); Debug.Assert(null != structuralType, "this method must be called only for entity/complextype reader function imports"); structuralTypes = new[] { structuralType }; } else { // Types are explicitly mapped. structuralTypes = resultMapping.MappedEntityTypes.Cast <StructuralType>(); } // Gather columns corresponding to all properties. foreach (var structuralType in structuralTypes) { foreach (EdmProperty property in TypeHelpers.GetAllStructuralMembers(structuralType)) { // NOTE: if a complex type is encountered, the column map generator will // throw. For now, we just let them through. // We expect to see each property multiple times, so we use indexer rather than // .Add. columns[property.Name] = property.TypeUsage; } } // Gather discriminator columns. foreach (var discriminatorColumn in GetDiscriminatorColumns(resultSetIndex)) { if (!columns.ContainsKey(discriminatorColumn)) { // CONSIDER: we assume that discriminatorColumns are all string types. In practice, // we're flexible about the runtime type during materialization, so the provider's // decision is hopefully irrelevant. The alternative is to require typed stored // procedure declarations in the SSDL, which is too much of a burden on the user and/or the // tools (there is no reliable way of determining this metadata automatically from SQL // Server). var type = TypeUsage.CreateStringTypeUsage( MetadataWorkspace.GetModelPrimitiveType(PrimitiveTypeKind.String), true, false); columns.Add(discriminatorColumn, type); } } // Expected type is a collection of rows var rowType = new RowType(columns.Select(c => new EdmProperty(c.Key, c.Value))); var result = TypeUsage.Create(new CollectionType(TypeUsage.Create(rowType))); return(result); }
public override TypeUsage GetStoreType(TypeUsage edmType) { if (edmType == null) { throw new ArgumentNullException("edmType"); } PrimitiveType primitiveType = edmType.EdmType as PrimitiveType; if (primitiveType == null) { throw new ArgumentException("Store does not support specified edm type"); } // TODO: come up with way to determin if unicode is used bool isUnicode = true; Facet facet; switch (primitiveType.PrimitiveTypeKind) { case PrimitiveTypeKind.Boolean: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["bool"])); case PrimitiveTypeKind.Int16: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"])); case PrimitiveTypeKind.Int32: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int4"])); case PrimitiveTypeKind.Int64: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int8"])); case PrimitiveTypeKind.Single: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float4"])); case PrimitiveTypeKind.Double: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["float8"])); case PrimitiveTypeKind.Decimal: { byte scale; byte precision; if (edmType.Facets.TryGetValue(ScaleFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { scale = (byte)facet.Value; if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { precision = (byte)facet.Value; return(TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"], precision, scale)); } } return(TypeUsage.CreateDecimalTypeUsage(StoreTypeNameToStorePrimitiveType["numeric"])); } case PrimitiveTypeKind.String: { // TODO: could get character, character varying, text if (edmType.Facets.TryGetValue(FixedLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null && (bool)facet.Value) { PrimitiveType characterPrimitive = StoreTypeNameToStorePrimitiveType["bpchar"]; if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true, (int)facet.Value)); } // this may not work well return(TypeUsage.CreateStringTypeUsage(characterPrimitive, isUnicode, true)); } if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["varchar"], isUnicode, false, (int)facet.Value)); } // assume text since it is not fixed length and has no max length return(TypeUsage.CreateStringTypeUsage(StoreTypeNameToStorePrimitiveType["text"], isUnicode, false)); } case PrimitiveTypeKind.DateTime: if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], (byte)facet.Value)); } else { return(TypeUsage.CreateDateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["timestamp"], null)); } case PrimitiveTypeKind.DateTimeOffset: if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], (byte)facet.Value)); } else { return(TypeUsage.CreateDateTimeOffsetTypeUsage(StoreTypeNameToStorePrimitiveType["timestamptz"], null)); } case PrimitiveTypeKind.Time: if (edmType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], (byte)facet.Value)); } else { return(TypeUsage.CreateTimeTypeUsage(StoreTypeNameToStorePrimitiveType["interval"], null)); } case PrimitiveTypeKind.Binary: { if (edmType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false, (int)facet.Value)); } return(TypeUsage.CreateBinaryTypeUsage(StoreTypeNameToStorePrimitiveType["bytea"], false)); } case PrimitiveTypeKind.Guid: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["uuid"])); case PrimitiveTypeKind.Byte: case PrimitiveTypeKind.SByte: return(TypeUsage.CreateDefaultTypeUsage(StoreTypeNameToStorePrimitiveType["int2"])); } throw new NotSupportedException("Not supported edm type: " + edmType); }
public override TypeUsage GetEdmType(TypeUsage storeType) { if (storeType == null) { throw new ArgumentNullException("storeType"); } string storeTypeName = storeType.EdmType.Name; PrimitiveType primitiveType = StoreTypeNameToEdmPrimitiveType[storeTypeName]; // TODO: come up with way to determin if unicode is used bool isUnicode = true; Facet facet; switch (storeTypeName) { case "bool": case "int2": case "int4": case "int8": case "float4": case "float8": case "uuid": return(TypeUsage.CreateDefaultTypeUsage(primitiveType)); case "numeric": { byte scale; byte precision; if (storeType.Facets.TryGetValue(ScaleFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { scale = (byte)facet.Value; if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { precision = (byte)facet.Value; return(TypeUsage.CreateDecimalTypeUsage(primitiveType, precision, scale)); } } return(TypeUsage.CreateDecimalTypeUsage(primitiveType)); } case "bpchar": if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true, (int)facet.Value)); } else { return(TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, true)); } case "varchar": if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false, (int)facet.Value)); } else { return(TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false)); } case "text": case "xml": return(TypeUsage.CreateStringTypeUsage(primitiveType, isUnicode, false)); case "timestamp": // TODO: make sure the arguments are correct here if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateDateTimeTypeUsage(primitiveType, (byte)facet.Value)); } else { return(TypeUsage.CreateDateTimeTypeUsage(primitiveType, null)); } case "date": return(TypeUsage.CreateDateTimeTypeUsage(primitiveType, 0)); case "timestamptz": if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, (byte)facet.Value)); } else { return(TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, null)); } case "time": case "interval": if (storeType.Facets.TryGetValue(PrecisionFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateTimeTypeUsage(primitiveType, (byte)facet.Value)); } else { return(TypeUsage.CreateTimeTypeUsage(primitiveType, null)); } case "bytea": { if (storeType.Facets.TryGetValue(MaxLengthFacet, false, out facet) && !facet.IsUnbounded && facet.Value != null) { return(TypeUsage.CreateBinaryTypeUsage(primitiveType, false, (int)facet.Value)); } return(TypeUsage.CreateBinaryTypeUsage(primitiveType, false)); } case "rowversion": { return(TypeUsage.CreateBinaryTypeUsage(primitiveType, true, 8)); } //TypeUsage.CreateBinaryTypeUsage //TypeUsage.CreateDateTimeTypeUsage //TypeUsage.CreateDecimalTypeUsage //TypeUsage.CreateStringTypeUsage } throw new NotSupportedException("Not supported store type: " + storeTypeName); }
private TypeUsage BuildTypeUsage() { var primitiveType = PrimitiveType.GetEdmPrimitiveType(Type); if (Type == PrimitiveTypeKind.Binary) { if (MaxLength != null) { return(TypeUsage.CreateBinaryTypeUsage( primitiveType, IsFixedLength ?? false, MaxLength.Value)); } return(TypeUsage.CreateBinaryTypeUsage( primitiveType, IsFixedLength ?? false)); } if (Type == PrimitiveTypeKind.String) { if (MaxLength != null) { return(TypeUsage.CreateStringTypeUsage( primitiveType, IsUnicode ?? true, IsFixedLength ?? false, MaxLength.Value)); } return(TypeUsage.CreateStringTypeUsage( primitiveType, IsUnicode ?? true, IsFixedLength ?? false)); } if (Type == PrimitiveTypeKind.DateTime) { return(TypeUsage.CreateDateTimeTypeUsage(primitiveType, Precision)); } if (Type == PrimitiveTypeKind.DateTimeOffset) { return(TypeUsage.CreateDateTimeOffsetTypeUsage(primitiveType, Precision)); } if (Type == PrimitiveTypeKind.Decimal) { if ((Precision != null) || (Scale != null)) { return(TypeUsage.CreateDecimalTypeUsage( primitiveType, Precision ?? 18, Scale ?? 0)); } return(TypeUsage.CreateDecimalTypeUsage(primitiveType)); } return((Type == PrimitiveTypeKind.Time) ? TypeUsage.CreateTimeTypeUsage(primitiveType, Precision) : TypeUsage.CreateDefaultTypeUsage(primitiveType)); }
internal static TypeUsage ForceNonUnicode(this TypeUsage typeUsage) { TypeUsage stringTypeUsage = TypeUsage.CreateStringTypeUsage((PrimitiveType)typeUsage.EdmType, false, false); return(TypeUsage.Create(typeUsage.EdmType, typeUsage.Facets.Where <Facet>((Func <Facet, bool>)(f => f.Name != "Unicode")).Union <Facet>(stringTypeUsage.Facets.Where <Facet>((Func <Facet, bool>)(f => f.Name == "Unicode"))))); }