1 //---------------------------------------------------------------------
2 // <copyright file="TypeHelpers.cs" company="Microsoft">
3 // Copyright(c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 namespace System
.Data
.Common
13 using System
.Collections
;
14 using System
.Collections
.Generic
;
16 using System
.Data
.Common
.CommandTrees
;
17 using System
.Data
.Metadata
.Edm
;
18 using System
.Data
.Objects
.ELinq
;
19 using System
.Diagnostics
;
20 using System
.Globalization
;
23 /// Represents a set of static Type helpers operating on TypeMetadata
25 internal static class TypeHelpers
30 /// Asserts types are in Model space
32 /// <param name="typeUsage"></param>
33 [Conditional("DEBUG")]
34 internal static void AssertEdmType(TypeUsage typeUsage
)
36 EdmType type
= typeUsage
.EdmType
;
37 if (TypeSemantics
.IsCollectionType(typeUsage
))
39 AssertEdmType(TypeHelpers
.GetElementTypeUsage(typeUsage
));
41 else if (TypeSemantics
.IsStructuralType(typeUsage
) && !Helper
.IsComplexType(typeUsage
.EdmType
) && !Helper
.IsEntityType(typeUsage
.EdmType
))
43 foreach (EdmMember m
in TypeHelpers
.GetDeclaredStructuralMembers(typeUsage
))
45 AssertEdmType(m
.TypeUsage
);
48 else if (TypeSemantics
.IsPrimitiveType(typeUsage
))
50 PrimitiveType pType
= type
as PrimitiveType
;
53 if (pType
.DataSpace
!= DataSpace
.CSpace
)
54 throw new NotSupportedException(String
.Format(CultureInfo
.InvariantCulture
, "PrimitiveType must be CSpace '{0}'", typeUsage
.ToString()));
60 /// Asserts querycommandtrees are in model space type terms
62 /// <param name="commandTree"></param>
63 [Conditional("DEBUG")]
64 internal static void AssertEdmType(DbCommandTree commandTree
)
66 DbQueryCommandTree queryCommandTree
= commandTree
as DbQueryCommandTree
;
67 if (null != queryCommandTree
)
69 AssertEdmType(queryCommandTree
.Query
.ResultType
);
77 #region Type Semantics
80 /// Determines whether a given typeUsage is valid as OrderBy sort key
82 /// <param name="typeUsage"></param>
83 /// <returns></returns>
84 internal static bool IsValidSortOpKeyType(TypeUsage typeUsage
)
86 if (TypeSemantics
.IsRowType(typeUsage
))
88 RowType rowType
= (RowType
)typeUsage
.EdmType
;
89 foreach (EdmProperty property
in rowType
.Properties
)
91 if (!IsValidSortOpKeyType(property
.TypeUsage
))
100 return TypeSemantics
.IsOrderComparable(typeUsage
);
105 /// Determines whether a given typeusage is valid as GroupBy key
107 /// <param name="typeUsage"></param>
108 /// <returns></returns>
109 internal static bool IsValidGroupKeyType(TypeUsage typeUsage
)
111 return IsSetComparableOpType(typeUsage
);
115 /// Determine wheter a given typeusage is valid for Distinct operator
117 /// <param name="typeUsage"></param>
118 /// <returns></returns>
119 internal static bool IsValidDistinctOpType(TypeUsage typeUsage
)
121 return IsSetComparableOpType(typeUsage
);
125 /// Determine wheter a given typeusage is valid for set comparison operator such as UNION, INTERSECT and EXCEPT
127 /// <param name="typeUsage"></param>
128 /// <returns></returns>
129 internal static bool IsSetComparableOpType(TypeUsage typeUsage
)
131 if (Helper
.IsEntityType(typeUsage
.EdmType
) ||
132 Helper
.IsPrimitiveType(typeUsage
.EdmType
) ||
133 Helper
.IsEnumType(typeUsage
.EdmType
) ||
134 Helper
.IsRefType(typeUsage
.EdmType
) )
138 else if (TypeSemantics
.IsRowType(typeUsage
))
140 RowType rowType
= (RowType
)typeUsage
.EdmType
;
141 foreach (EdmProperty property
in rowType
.Properties
)
143 if (!IsSetComparableOpType(property
.TypeUsage
))
154 /// Returns true if typeUsage type is valid for IS [NOT] NULL (expr) operator
156 /// <param name="typeUsage"></param>
157 /// <returns></returns>
158 internal static bool IsValidIsNullOpType(TypeUsage typeUsage
)
160 return TypeSemantics
.IsReferenceType(typeUsage
) ||
161 TypeSemantics
.IsEntityType(typeUsage
) ||
162 TypeSemantics
.IsScalarType(typeUsage
);
166 internal static bool IsValidInOpType(TypeUsage typeUsage
)
168 return TypeSemantics
.IsReferenceType(typeUsage
) ||
169 TypeSemantics
.IsEntityType(typeUsage
) ||
170 TypeSemantics
.IsScalarType(typeUsage
);
173 internal static TypeUsage
GetCommonTypeUsage(TypeUsage typeUsage1
, TypeUsage typeUsage2
)
175 return TypeSemantics
.GetCommonType(typeUsage1
, typeUsage2
);
178 internal static TypeUsage
GetCommonTypeUsage(IEnumerable
<TypeUsage
> types
)
180 TypeUsage commonType
= null;
181 foreach (TypeUsage testType
in types
)
183 if (null == testType
)
188 if (null == commonType
)
190 commonType
= testType
;
194 commonType
= TypeSemantics
.GetCommonType(commonType
, testType
);
195 if (null == commonType
)
207 // Type property extractors
209 #region Type property extractors
211 internal static bool TryGetClosestPromotableType(TypeUsage fromType
, out TypeUsage promotableType
)
213 promotableType
= null;
214 if (Helper
.IsPrimitiveType(fromType
.EdmType
))
216 PrimitiveType fromPrimitiveType
= (PrimitiveType
)fromType
.EdmType
;
217 IList
<PrimitiveType
> promotableTypes
= EdmProviderManifest
.Instance
.GetPromotionTypes(fromPrimitiveType
);
218 int index
= promotableTypes
.IndexOf(fromPrimitiveType
);
219 if (-1 != index
&& index
+ 1 < promotableTypes
.Count
)
221 promotableType
= TypeUsage
.Create(promotableTypes
[index
+ 1]);
224 return (null != promotableType
);
233 #region Facet Helpers
235 internal static bool TryGetBooleanFacetValue(TypeUsage type
, string facetName
, out bool boolValue
)
239 if (type
.Facets
.TryGetValue(facetName
, false, out boolFacet
) && boolFacet
.Value
!= null)
241 boolValue
= (bool)boolFacet
.Value
;
248 internal static bool TryGetByteFacetValue(TypeUsage type
, string facetName
, out byte byteValue
)
252 if (type
.Facets
.TryGetValue(facetName
, false, out byteFacet
) && byteFacet
.Value
!= null && !Helper
.IsUnboundedFacetValue(byteFacet
))
254 byteValue
= (byte)byteFacet
.Value
;
261 internal static bool TryGetIntFacetValue(TypeUsage type
, string facetName
, out int intValue
)
265 if (type
.Facets
.TryGetValue(facetName
, false, out intFacet
) && intFacet
.Value
!= null && !Helper
.IsUnboundedFacetValue(intFacet
) && !Helper
.IsVariableFacetValue(intFacet
))
267 intValue
= (int)intFacet
.Value
;
274 internal static bool TryGetIsFixedLength(TypeUsage type
, out bool isFixedLength
)
276 if (!TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.String
) &&
277 !TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.Binary
))
279 isFixedLength
= false;
283 // Binary and String MaxLength facets share the same name
284 return TypeHelpers
.TryGetBooleanFacetValue(type
, DbProviderManifest
.FixedLengthFacetName
, out isFixedLength
);
287 internal static bool TryGetIsUnicode(TypeUsage type
, out bool isUnicode
)
289 if (!TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.String
))
295 return TypeHelpers
.TryGetBooleanFacetValue(type
, DbProviderManifest
.UnicodeFacetName
, out isUnicode
);
298 internal static bool IsFacetValueConstant(TypeUsage type
, string facetName
)
300 // Binary and String FixedLength facets share the same name
301 return Helper
.GetFacet(((PrimitiveType
)type
.EdmType
).FacetDescriptions
, facetName
).IsConstant
;
304 internal static bool TryGetMaxLength(TypeUsage type
, out int maxLength
)
306 if (!TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.String
) &&
307 !TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.Binary
))
313 // Binary and String FixedLength facets share the same name
314 return TypeHelpers
.TryGetIntFacetValue(type
, DbProviderManifest
.MaxLengthFacetName
, out maxLength
);
317 internal static bool TryGetPrecision(TypeUsage type
, out byte precision
)
319 if (!TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.Decimal
))
325 return TypeHelpers
.TryGetByteFacetValue(type
, DbProviderManifest
.PrecisionFacetName
, out precision
);
328 internal static bool TryGetScale(TypeUsage type
, out byte scale
)
330 if (!TypeSemantics
.IsPrimitiveType(type
, PrimitiveTypeKind
.Decimal
))
336 return TypeHelpers
.TryGetByteFacetValue(type
, DbProviderManifest
.ScaleFacetName
, out scale
);
339 internal static bool TryGetPrimitiveTypeKind(TypeUsage type
, out PrimitiveTypeKind typeKind
)
341 if (type
!= null && type
.EdmType
!= null && type
.EdmType
.BuiltInTypeKind
== BuiltInTypeKind
.PrimitiveType
)
343 typeKind
= ((PrimitiveType
)type
.EdmType
).PrimitiveTypeKind
;
347 typeKind
= default(PrimitiveTypeKind
);
356 #region Type Constructors
357 internal static CollectionType
CreateCollectionType(TypeUsage elementType
)
359 return new CollectionType(elementType
);
362 internal static TypeUsage
CreateCollectionTypeUsage(TypeUsage elementType
)
364 return CreateCollectionTypeUsage(elementType
, false /* readOnly */ );
367 internal static TypeUsage
CreateCollectionTypeUsage(TypeUsage elementType
, bool readOnly
)
369 return TypeUsage
.Create(new CollectionType(elementType
));
372 internal static RowType
CreateRowType(IEnumerable
<KeyValuePair
<string, TypeUsage
>> columns
)
374 return CreateRowType(columns
, null);
377 internal static RowType
CreateRowType(IEnumerable
<KeyValuePair
<string, TypeUsage
>> columns
, InitializerMetadata initializerMetadata
)
379 List
<EdmProperty
> rowElements
= new List
<EdmProperty
>();
380 foreach (KeyValuePair
<string, TypeUsage
> kvp
in columns
)
382 rowElements
.Add(new EdmProperty(kvp
.Key
, kvp
.Value
));
384 return new RowType(rowElements
, initializerMetadata
);
387 internal static TypeUsage
CreateRowTypeUsage(IEnumerable
<KeyValuePair
<string, TypeUsage
>> columns
, bool readOnly
)
389 return TypeUsage
.Create(CreateRowType(columns
));
392 internal static RefType
CreateReferenceType(EntityTypeBase entityType
)
394 return new RefType((EntityType
)entityType
);
397 internal static TypeUsage
CreateReferenceTypeUsage(EntityType entityType
)
399 return TypeUsage
.Create(CreateReferenceType(entityType
));
403 /// Creates metadata for a new row type with column names and types based on the key members of the specified Entity type
405 /// <param name="entityType">The Entity type that provides the Key members on which the column names and types of the new row type will be based</param>
406 /// <returns>A new RowType info with column names and types corresponding to the Key members of the specified Entity type</returns>
407 internal static RowType
CreateKeyRowType(EntityTypeBase entityType
)
409 IEnumerable
<EdmMember
> entityKeys
= entityType
.KeyMembers
;
410 if (null == entityKeys
)
412 throw EntityUtil
.Argument(System
.Data
.Entity
.Strings
.Cqt_Metadata_EntityTypeNullKeyMembersInvalid
, "entityType");
415 List
<KeyValuePair
<string, TypeUsage
>> resultCols
= new List
<KeyValuePair
<string, TypeUsage
>>();
417 foreach (EdmProperty keyProperty
in entityKeys
)
419 //this.CheckMember(keyProperty, "property", CommandTreeUtils.FormatIndex("entityType.KeyMembers", idx++));
420 resultCols
.Add(new KeyValuePair
<string, TypeUsage
>(keyProperty
.Name
, Helper
.GetModelTypeUsage(keyProperty
)));
423 if (resultCols
.Count
< 1)
425 throw EntityUtil
.Argument(System
.Data
.Entity
.Strings
.Cqt_Metadata_EntityTypeEmptyKeyMembersInvalid
, "entityType");
428 return TypeHelpers
.CreateRowType(resultCols
);
432 /// Gets primitive type usage for <paramref name="scalarType"/>.
434 /// <param name="scalarType">Primitive or enum type usage.</param>
436 /// Primitive type usage for <paramref name="scalarType"/>.
439 /// For enum types a new type usage based on the underlying type will be created. For primitive types
440 /// the value passed to the function will be returned.
442 internal static TypeUsage
GetPrimitiveTypeUsageForScalar(TypeUsage scalarType
)
444 Debug
.Assert(scalarType
!= null, "scalarType != null");
445 Debug
.Assert(TypeSemantics
.IsScalarType(scalarType
), "Primitive or enum type expected.");
447 return TypeSemantics
.IsEnumerationType(scalarType
) ?
448 CreateEnumUnderlyingTypeUsage(scalarType
) :
453 /// Factory method for creating a type usage for underlying type of enum type usage.
455 /// <param name="enumTypeUsage">Enum type usage used to create an underlying type usage of.</param>
456 /// <returns>Type usage for the underlying enum type.</returns>
457 internal static TypeUsage
CreateEnumUnderlyingTypeUsage(TypeUsage enumTypeUsage
)
459 Debug
.Assert(enumTypeUsage
!= null, "enumTypeUsage != null");
460 Debug
.Assert(TypeSemantics
.IsEnumerationType(enumTypeUsage
), "enumTypeUsage is not an enumerated type");
462 return TypeUsage
.Create(Helper
.GetUnderlyingEdmTypeForEnumType(enumTypeUsage
.EdmType
), enumTypeUsage
.Facets
);
466 /// Factory method for creating a type usage for underlying union type of spatial type usage.
468 /// <param name="spatialTypeUsage">Spatial type usage used to create a union type usage of.</param>
469 /// <returns>Type usage for the spatial union type of the correct topology.</returns>
470 internal static TypeUsage
CreateSpatialUnionTypeUsage(TypeUsage spatialTypeUsage
)
472 Debug
.Assert(spatialTypeUsage
!= null, "spatialTypeUsage != null");
473 Debug
.Assert(TypeSemantics
.IsStrongSpatialType(spatialTypeUsage
), "spatialTypeUsage is not a strong spatial type");
474 return TypeUsage
.Create(Helper
.GetSpatialNormalizedPrimitiveType(spatialTypeUsage
.EdmType
), spatialTypeUsage
.Facets
);
482 #region Type Extractors
485 /// Retrieves Properties and/or RelationshipEnds declared by the specified type or any base type.
487 /// <param name="type"></param>
488 /// <returns></returns>
489 internal static IBaseList
<EdmMember
> GetAllStructuralMembers(TypeUsage type
)
491 return GetAllStructuralMembers(type
.EdmType
);
494 internal static IBaseList
<EdmMember
> GetAllStructuralMembers(EdmType edmType
)
496 System
.Diagnostics
.Debug
.Assert(edmType
!= null);
497 switch (edmType
.BuiltInTypeKind
)
499 case BuiltInTypeKind
.AssociationType
:
500 return (IBaseList
<EdmMember
>)((AssociationType
)edmType
).AssociationEndMembers
;
501 case BuiltInTypeKind
.ComplexType
:
502 return (IBaseList
<EdmMember
>)((ComplexType
)edmType
).Properties
;
503 case BuiltInTypeKind
.EntityType
:
504 return (IBaseList
<EdmMember
>)((EntityType
)edmType
).Properties
;
505 case BuiltInTypeKind
.RowType
:
506 return (IBaseList
<EdmMember
>)((RowType
)edmType
).Properties
;
508 return EmptyArrayEdmProperty
;
513 /// Retrieves Properties and/or RelationshipEnds declared by (and ONLY by) the specified type.
515 /// <param name="type"></param>
516 /// <returns></returns>
517 internal static IEnumerable
GetDeclaredStructuralMembers(TypeUsage type
)
519 return GetDeclaredStructuralMembers(type
.EdmType
);
523 /// Retrieves Properties and/or RelationshipEnds declared by (and ONLY by) the specified type.
525 /// <param name="edmType"></param>
526 /// <returns></returns>
527 internal static IEnumerable
GetDeclaredStructuralMembers(EdmType edmType
)
529 switch (edmType
.BuiltInTypeKind
)
531 case BuiltInTypeKind
.AssociationType
:
532 return ((AssociationType
)edmType
).GetDeclaredOnlyMembers
<AssociationEndMember
>();
533 case BuiltInTypeKind
.ComplexType
:
534 return ((ComplexType
)edmType
).GetDeclaredOnlyMembers
<EdmProperty
>();
535 case BuiltInTypeKind
.EntityType
:
536 return ((EntityType
)edmType
).GetDeclaredOnlyMembers
<EdmProperty
>();
537 case BuiltInTypeKind
.RowType
:
538 return ((RowType
)edmType
).GetDeclaredOnlyMembers
<EdmProperty
>();
540 return EmptyArrayEdmProperty
;
544 internal static readonly ReadOnlyMetadataCollection
<EdmMember
> EmptyArrayEdmMember
= new ReadOnlyMetadataCollection
<EdmMember
>(new MetadataCollection
<EdmMember
>().SetReadOnly());
545 internal static readonly FilteredReadOnlyMetadataCollection
<EdmProperty
, EdmMember
> EmptyArrayEdmProperty
= new FilteredReadOnlyMetadataCollection
<EdmProperty
, EdmMember
>(EmptyArrayEdmMember
, null);
547 internal static ReadOnlyMetadataCollection
<EdmProperty
> GetProperties(TypeUsage typeUsage
)
549 return GetProperties(typeUsage
.EdmType
);
552 internal static ReadOnlyMetadataCollection
<EdmProperty
> GetProperties(EdmType edmType
)
554 switch (edmType
.BuiltInTypeKind
)
556 case BuiltInTypeKind
.ComplexType
:
557 return ((ComplexType
)edmType
).Properties
;
558 case BuiltInTypeKind
.EntityType
:
559 return ((EntityType
)edmType
).Properties
;
560 case BuiltInTypeKind
.RowType
:
561 return ((RowType
)edmType
).Properties
;
563 return EmptyArrayEdmProperty
;
567 internal static TypeUsage
GetElementTypeUsage(TypeUsage type
)
569 if (TypeSemantics
.IsCollectionType(type
))
571 return ((CollectionType
)type
.EdmType
).TypeUsage
;
573 else if (TypeSemantics
.IsReferenceType(type
))
575 return TypeUsage
.Create(((RefType
)type
.EdmType
).ElementType
);
582 /// Returns row type if supplied function is a tvf returning Collection(RowType), otherwise null.
584 internal static RowType
GetTvfReturnType(EdmFunction tvf
)
586 if (tvf
.ReturnParameter
!= null && TypeSemantics
.IsCollectionType(tvf
.ReturnParameter
.TypeUsage
))
588 var expectedElementTypeUsage
= ((CollectionType
)tvf
.ReturnParameter
.TypeUsage
.EdmType
).TypeUsage
;
589 if (TypeSemantics
.IsRowType(expectedElementTypeUsage
))
591 return (RowType
)expectedElementTypeUsage
.EdmType
;
600 internal static bool TryGetCollectionElementType(TypeUsage type
, out TypeUsage elementType
)
602 CollectionType collectionType
;
603 if (TypeHelpers
.TryGetEdmType
<CollectionType
>(type
, out collectionType
))
605 elementType
= collectionType
.TypeUsage
;
606 return (elementType
!= null);
614 /// If the type refered to by the TypeUsage is a RefType, extracts the EntityType and returns true,
615 /// otherwise returns false.
617 /// <param name="type">TypeUsage that may or may not refer to a RefType</param>
618 /// <param name="referencedEntityType">Non-null if the TypeUsage refers to a RefType, null otherwise</param>
619 /// <returns>True if the TypeUsage refers to a RefType, false otherwise</returns>
620 internal static bool TryGetRefEntityType(TypeUsage type
, out EntityType referencedEntityType
)
623 if (TryGetEdmType
<RefType
>(type
, out refType
) &&
624 Helper
.IsEntityType(refType
.ElementType
))
626 referencedEntityType
= (EntityType
)refType
.ElementType
;
630 referencedEntityType
= null;
634 internal static TEdmType GetEdmType
<TEdmType
>(TypeUsage typeUsage
)
635 where TEdmType
: EdmType
637 return (TEdmType
)typeUsage
.EdmType
;
640 internal static bool TryGetEdmType
<TEdmType
>(TypeUsage typeUsage
, out TEdmType type
)
641 where TEdmType
: EdmType
643 type
= typeUsage
.EdmType
as TEdmType
;
644 return (type
!= null);
652 internal static TypeUsage
GetReadOnlyType(TypeUsage type
)
654 if (!(type
.IsReadOnly
))
665 internal static string GetFullName(TypeUsage type
)
667 return type
.ToString();
670 internal static string GetFullName(EdmType type
)
672 return GetFullName(type
.NamespaceName
, type
.Name
);
675 internal static string GetFullName(EntitySetBase entitySet
)
677 Debug
.Assert(entitySet
.EntityContainer
!= null, "entitySet.EntityContainer is null");
678 return GetFullName(entitySet
.EntityContainer
.Name
, entitySet
.Name
);
681 internal static string GetFullName(string qualifier
, string name
)
683 if (string.IsNullOrEmpty(qualifier
))
685 return string.Format(CultureInfo
.InvariantCulture
, "{0}", name
);
689 return string.Format(CultureInfo
.InvariantCulture
, "{0}.{1}", qualifier
, name
);
694 /// Converts the given CLR type into a DbType
696 /// <param name="clrType">The CLR type to convert</param>
697 /// <returns></returns>
698 internal static DbType
ConvertClrTypeToDbType(Type clrType
)
700 switch (Type
.GetTypeCode(clrType
))
703 throw EntityUtil
.InvalidDataType(TypeCode
.Empty
);
705 case TypeCode
.Object
:
706 if (clrType
== typeof(System
.Byte
[]))
708 return DbType
.Binary
;
710 if (clrType
== typeof(System
.Char
[]))
712 // Always treat char and char[] as string
713 return DbType
.String
;
715 else if (clrType
== typeof(System
.Guid
))
719 else if (clrType
== typeof(System
.TimeSpan
))
723 else if (clrType
== typeof(System
.DateTimeOffset
))
725 return DbType
.DateTimeOffset
;
728 return DbType
.Object
;
730 case TypeCode
.DBNull
:
731 return DbType
.Object
;
732 case TypeCode
.Boolean
:
733 return DbType
.Boolean
;
739 // Always treat char and char[] as string
740 return DbType
.String
;
743 case TypeCode
.UInt16
:
744 return DbType
.UInt16
;
747 case TypeCode
.UInt32
:
748 return DbType
.UInt32
;
751 case TypeCode
.UInt64
:
752 return DbType
.UInt64
;
753 case TypeCode
.Single
:
754 return DbType
.Single
;
755 case TypeCode
.Double
:
756 return DbType
.Double
;
757 case TypeCode
.Decimal
:
758 return DbType
.Decimal
;
759 case TypeCode
.DateTime
:
760 return DbType
.DateTime
;
761 case TypeCode
.String
:
762 return DbType
.String
;
764 throw EntityUtil
.UnknownDataTypeCode(clrType
, Type
.GetTypeCode(clrType
));
768 internal static bool IsIntegerConstant(TypeUsage valueType
, object value, long expectedValue
)
770 if (!TypeSemantics
.IsIntegerNumericType(valueType
))
780 PrimitiveType intType
= (PrimitiveType
)valueType
.EdmType
;
781 switch (intType
.PrimitiveTypeKind
)
783 case PrimitiveTypeKind
.Byte
:
784 return (expectedValue
== (byte)value);
786 case PrimitiveTypeKind
.Int16
:
787 return (expectedValue
== (short)value);
789 case PrimitiveTypeKind
.Int32
:
790 return (expectedValue
== (int)value);
792 case PrimitiveTypeKind
.Int64
:
793 return (expectedValue
== (long)value);
795 case PrimitiveTypeKind
.SByte
:
796 return (expectedValue
== (sbyte)value);
800 Debug
.Assert(false, "Integer primitive type was not one of Byte, Int16, Int32, Int64, SByte?");
807 /// returns a Typeusage
809 /// <param name="primitiveTypeKind"></param>
810 /// <returns></returns>
811 static internal TypeUsage
GetLiteralTypeUsage(PrimitiveTypeKind primitiveTypeKind
)
813 // all clr strings by default are unicode
814 return GetLiteralTypeUsage(primitiveTypeKind
, true /* unicode */);
817 static internal TypeUsage
GetLiteralTypeUsage(PrimitiveTypeKind primitiveTypeKind
, bool isUnicode
)
820 PrimitiveType primitiveType
= EdmProviderManifest
.Instance
.GetPrimitiveType(primitiveTypeKind
);
821 switch (primitiveTypeKind
)
823 case PrimitiveTypeKind
.String
:
824 typeusage
= TypeUsage
.Create(primitiveType
,
825 new FacetValues{ Unicode = isUnicode, MaxLength = TypeUsage.DefaultMaxLengthFacetValue, FixedLength = false, Nullable = false}
);
829 typeusage
= TypeUsage
.Create(primitiveType
,
830 new FacetValues{ Nullable = false }
);
838 #region EdmFunction Helpers
839 internal static bool IsCanonicalFunction(EdmFunction function
)
841 bool isCanonicalFunction
= (function
.DataSpace
== DataSpace
.CSpace
&& function
.NamespaceName
== EdmConstants
.EdmNamespace
);
843 Debug
.Assert(!isCanonicalFunction
|| (isCanonicalFunction
&& !function
.HasUserDefinedBody
),
844 "Canonical function '" + function
.FullName
+ "' can not have a user defined body");
846 return isCanonicalFunction
;