internal static bool IsPromotableTo(TypeUsage fromType, TypeUsage toType) { if (toType.EdmType.EdmEquals((MetadataItem)fromType.EdmType)) { return(true); } if (Helper.IsPrimitiveType(fromType.EdmType) && Helper.IsPrimitiveType(toType.EdmType)) { return(TypeSemantics.IsPrimitiveTypePromotableTo(fromType, toType)); } if (Helper.IsCollectionType((GlobalItem)fromType.EdmType) && Helper.IsCollectionType((GlobalItem)toType.EdmType)) { return(TypeSemantics.IsPromotableTo(TypeHelpers.GetElementTypeUsage(fromType), TypeHelpers.GetElementTypeUsage(toType))); } if (Helper.IsEntityTypeBase(fromType.EdmType) && Helper.IsEntityTypeBase(toType.EdmType)) { return(fromType.EdmType.IsSubtypeOf(toType.EdmType)); } if (Helper.IsRefType((GlobalItem)fromType.EdmType) && Helper.IsRefType((GlobalItem)toType.EdmType)) { return(TypeSemantics.IsPromotableTo(TypeHelpers.GetElementTypeUsage(fromType), TypeHelpers.GetElementTypeUsage(toType))); } if (Helper.IsRowType((GlobalItem)fromType.EdmType) && Helper.IsRowType((GlobalItem)toType.EdmType)) { return(TypeSemantics.IsPromotableTo((RowType)fromType.EdmType, (RowType)toType.EdmType)); } return(false); }
// <summary> // Flattens composite transient type down to nominal type leafs. // </summary> internal static IEnumerable <TypeUsage> FlattenType(TypeUsage type) { Func <TypeUsage, bool> isLeaf = t => !Helper.IsTransientType(t.EdmType); Func <TypeUsage, IEnumerable <TypeUsage> > getImmediateSubNodes = t => { if (Helper.IsCollectionType(t.EdmType) || Helper.IsRefType(t.EdmType)) { return(new[] { TypeHelpers.GetElementTypeUsage(t) }); } else if (Helper.IsRowType(t.EdmType)) { return(((RowType)t.EdmType).Properties.Select(p => p.TypeUsage)); } else { Debug.Fail("cannot enumerate subnodes of a leaf node"); return(new TypeUsage[] { }); } }; return(Helpers.GetLeafNodes(type, isLeaf, getImmediateSubNodes)); }
private static bool TryGetCommonType( EdmType edmType1, EdmType edmType2, out EdmType commonEdmType) { if (edmType2 == edmType1) { commonEdmType = edmType1; return(true); } if (Helper.IsPrimitiveType(edmType1) && Helper.IsPrimitiveType(edmType2)) { return(TypeSemantics.TryGetCommonType((PrimitiveType)edmType1, (PrimitiveType)edmType2, out commonEdmType)); } if (Helper.IsCollectionType((GlobalItem)edmType1) && Helper.IsCollectionType((GlobalItem)edmType2)) { return(TypeSemantics.TryGetCommonType((CollectionType)edmType1, (CollectionType)edmType2, out commonEdmType)); } if (Helper.IsEntityTypeBase(edmType1) && Helper.IsEntityTypeBase(edmType2)) { return(TypeSemantics.TryGetCommonBaseType(edmType1, edmType2, out commonEdmType)); } if (Helper.IsRefType((GlobalItem)edmType1) && Helper.IsRefType((GlobalItem)edmType2)) { return(TypeSemantics.TryGetCommonType((RefType)edmType1, (RefType)edmType2, out commonEdmType)); } if (Helper.IsRowType((GlobalItem)edmType1) && Helper.IsRowType((GlobalItem)edmType2)) { return(TypeSemantics.TryGetCommonType((RowType)edmType1, (RowType)edmType2, out commonEdmType)); } commonEdmType = (EdmType)null; return(false); }
internal static bool IsTransientType(EdmType edmType) { if (!Helper.IsCollectionType((GlobalItem)edmType) && !Helper.IsRefType((GlobalItem)edmType)) { return(Helper.IsRowType((GlobalItem)edmType)); } return(true); }
// <summary> // Determines if fromType is promotable to toType. // </summary> // <returns> true if fromType is promotable to toType, false otherwise </returns> internal static bool IsPromotableTo(TypeUsage fromType, TypeUsage toType) { DebugCheck.NotNull(fromType); DebugCheck.NotNull(toType); if (toType.EdmType.EdmEquals(fromType.EdmType)) { return(true); } if (Helper.IsPrimitiveType(fromType.EdmType) && Helper.IsPrimitiveType(toType.EdmType)) { return(IsPrimitiveTypePromotableTo( fromType, toType)); } else if (Helper.IsCollectionType(fromType.EdmType) && Helper.IsCollectionType(toType.EdmType)) { return(IsPromotableTo( TypeHelpers.GetElementTypeUsage(fromType), TypeHelpers.GetElementTypeUsage(toType))); } else if (Helper.IsEntityTypeBase(fromType.EdmType) && Helper.IsEntityTypeBase(toType.EdmType)) { return(fromType.EdmType.IsSubtypeOf(toType.EdmType)); } else if (Helper.IsRefType(fromType.EdmType) && Helper.IsRefType(toType.EdmType)) { return(IsPromotableTo( TypeHelpers.GetElementTypeUsage(fromType), TypeHelpers.GetElementTypeUsage(toType))); } else if (Helper.IsRowType(fromType.EdmType) && Helper.IsRowType(toType.EdmType)) { return(IsPromotableTo( (RowType)fromType.EdmType, (RowType)toType.EdmType)); } return(false); }
private static bool IsEqualComparable(EdmType edmType) { if (Helper.IsPrimitiveType(edmType) || Helper.IsRefType((GlobalItem)edmType) || (Helper.IsEntityType(edmType) || Helper.IsEnumType(edmType))) { return(true); } if (!Helper.IsRowType((GlobalItem)edmType)) { return(false); } foreach (EdmMember property in ((RowType)edmType).Properties) { if (!TypeSemantics.IsEqualComparable(property.TypeUsage)) { return(false); } } return(true); }
internal static IEnumerable <TypeUsage> FlattenType(TypeUsage type) { Func <TypeUsage, bool> isLeaf = (Func <TypeUsage, bool>)(t => !Helper.IsTransientType(t.EdmType)); Func <TypeUsage, IEnumerable <TypeUsage> > getImmediateSubNodes = (Func <TypeUsage, IEnumerable <TypeUsage> >)(t => { if (Helper.IsCollectionType((GlobalItem)t.EdmType) || Helper.IsRefType((GlobalItem)t.EdmType)) { return (IEnumerable <TypeUsage>) new TypeUsage[1] { TypeHelpers.GetElementTypeUsage(t) } } ; if (Helper.IsRowType((GlobalItem)t.EdmType)) { return(((RowType)t.EdmType).Properties.Select <EdmProperty, TypeUsage>((Func <EdmProperty, TypeUsage>)(p => p.TypeUsage))); } return((IEnumerable <TypeUsage>) new TypeUsage[0]); }); return(Helpers.GetLeafNodes <TypeUsage>(type, isLeaf, getImmediateSubNodes)); }
// <summary> // Determines if the given edmType is equal comparable. Consult "EntitySql Language Specification", // section 7 - Comparison and Dependent Operations for details. // </summary> // <param name="edmType"> an instance of an EdmType </param> // <returns> true if edmType is equal-comparable, false otherwise </returns> private static bool IsEqualComparable(EdmType edmType) { if (Helper.IsPrimitiveType(edmType) || Helper.IsRefType(edmType) || Helper.IsEntityType(edmType) || Helper.IsEnumType(edmType)) { return(true); } else if (Helper.IsRowType(edmType)) { var rowType = (RowType)edmType; foreach (var rowProperty in rowType.Properties) { if (!IsEqualComparable(rowProperty.TypeUsage)) { return(false); } } return(true); } return(false); }
/// <summary> /// Returns a Model type usage for a provider type /// </summary> /// <returns> model (CSpace) type usage </returns> internal TypeUsage GetModelTypeUsage() { if (_modelTypeUsage == null) { var edmType = EdmType; // If the edm type is already a cspace type, return the same type if (edmType.DataSpace == DataSpace.CSpace || edmType.DataSpace == DataSpace.OSpace) { return(this); } TypeUsage result; if (Helper.IsRowType(edmType)) { var sspaceRowType = (RowType)edmType; var properties = new EdmProperty[sspaceRowType.Properties.Count]; for (var i = 0; i < properties.Length; i++) { var sspaceProperty = sspaceRowType.Properties[i]; var newTypeUsage = sspaceProperty.TypeUsage.GetModelTypeUsage(); properties[i] = new EdmProperty(sspaceProperty.Name, newTypeUsage); } var edmRowType = new RowType(properties, sspaceRowType.InitializerMetadata); result = Create(edmRowType, Facets); } else if (Helper.IsCollectionType(edmType)) { var sspaceCollectionType = ((CollectionType)edmType); var newTypeUsage = sspaceCollectionType.TypeUsage.GetModelTypeUsage(); result = Create(new CollectionType(newTypeUsage), Facets); } else if (Helper.IsRefType(edmType)) { Debug.Assert(((RefType)edmType).ElementType.DataSpace == DataSpace.CSpace); result = this; } else if (Helper.IsPrimitiveType(edmType)) { result = ((PrimitiveType)edmType).ProviderManifest.GetEdmType(this); if (result == null) { throw new ProviderIncompatibleException(Strings.Mapping_ProviderReturnsNullType(ToString())); } if (!TypeSemantics.IsNullable(this)) { result = Create( result.EdmType, OverrideFacetValues( result.Facets, new FacetValues { Nullable = false })); } } else if (Helper.IsEntityTypeBase(edmType) || Helper.IsComplexType(edmType)) { result = this; } else { Debug.Assert(false, "Unexpected type found in entity data reader"); return(null); } Interlocked.CompareExchange(ref _modelTypeUsage, result, null); } return(_modelTypeUsage); }
private static bool TryGetCommonType(EdmType edmType1, EdmType edmType2, out EdmType commonEdmType) { DebugCheck.NotNull(edmType1); DebugCheck.NotNull(edmType2); if (edmType2 == edmType1) { commonEdmType = edmType1; return(true); } if (Helper.IsPrimitiveType(edmType1) && Helper.IsPrimitiveType(edmType2)) { return(TryGetCommonType( (PrimitiveType)edmType1, (PrimitiveType)edmType2, out commonEdmType)); } else if (Helper.IsCollectionType(edmType1) && Helper.IsCollectionType(edmType2)) { return(TryGetCommonType( (CollectionType)edmType1, (CollectionType)edmType2, out commonEdmType)); } else if (Helper.IsEntityTypeBase(edmType1) && Helper.IsEntityTypeBase(edmType2)) { return(TryGetCommonBaseType( edmType1, edmType2, out commonEdmType)); } else if (Helper.IsRefType(edmType1) && Helper.IsRefType(edmType2)) { return(TryGetCommonType( (RefType)edmType1, (RefType)edmType2, out commonEdmType)); } else if (Helper.IsRowType(edmType1) && Helper.IsRowType(edmType2)) { return(TryGetCommonType( (RowType)edmType1, (RowType)edmType2, out commonEdmType)); } else { commonEdmType = null; return(false); } }
// <summary> // determines if type is a ReferenceType // </summary> internal static bool IsReferenceType(TypeUsage type) { return(Helper.IsRefType(type.EdmType)); }