Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Data.Entity / System / Data / Metadata / TypeHelpers.cs
bloba08529d31d219ff48f14055cee126613a3ec452c
1 //---------------------------------------------------------------------
2 // <copyright file="TypeHelpers.cs" company="Microsoft">
3 // Copyright(c) Microsoft Corporation. All rights reserved.
4 // </copyright>
5 //
6 // @owner Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
10 namespace System.Data.Common
12 using System;
13 using System.Collections;
14 using System.Collections.Generic;
15 using System.Data;
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;
22 /// <summary>
23 /// Represents a set of static Type helpers operating on TypeMetadata
24 /// </summary>
25 internal static class TypeHelpers
27 #region Assert Types
29 /// <summary>
30 /// Asserts types are in Model space
31 /// </summary>
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;
51 if (null != pType)
53 if (pType.DataSpace != DataSpace.CSpace)
54 throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture, "PrimitiveType must be CSpace '{0}'", typeUsage.ToString()));
59 /// <summary>
60 /// Asserts querycommandtrees are in model space type terms
61 /// </summary>
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);
72 #endregion
75 // Type Semantics
77 #region Type Semantics
79 /// <summary>
80 /// Determines whether a given typeUsage is valid as OrderBy sort key
81 /// </summary>
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))
93 return false;
96 return true;
98 else
100 return TypeSemantics.IsOrderComparable(typeUsage);
104 /// <summary>
105 /// Determines whether a given typeusage is valid as GroupBy key
106 /// </summary>
107 /// <param name="typeUsage"></param>
108 /// <returns></returns>
109 internal static bool IsValidGroupKeyType(TypeUsage typeUsage)
111 return IsSetComparableOpType(typeUsage);
114 /// <summary>
115 /// Determine wheter a given typeusage is valid for Distinct operator
116 /// </summary>
117 /// <param name="typeUsage"></param>
118 /// <returns></returns>
119 internal static bool IsValidDistinctOpType(TypeUsage typeUsage)
121 return IsSetComparableOpType(typeUsage);
124 /// <summary>
125 /// Determine wheter a given typeusage is valid for set comparison operator such as UNION, INTERSECT and EXCEPT
126 /// </summary>
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) )
136 return true;
138 else if (TypeSemantics.IsRowType(typeUsage))
140 RowType rowType = (RowType)typeUsage.EdmType;
141 foreach (EdmProperty property in rowType.Properties)
143 if (!IsSetComparableOpType(property.TypeUsage))
145 return false;
148 return true;
150 return false;
153 /// <summary>
154 /// Returns true if typeUsage type is valid for IS [NOT] NULL (expr) operator
155 /// </summary>
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)
185 return null;
188 if (null == commonType)
190 commonType = testType;
192 else
194 commonType = TypeSemantics.GetCommonType(commonType, testType);
195 if (null == commonType)
197 break;
201 return commonType;
204 #endregion
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);
228 #endregion
231 // Facet Helpers
233 #region Facet Helpers
235 internal static bool TryGetBooleanFacetValue(TypeUsage type, string facetName, out bool boolValue)
237 boolValue = false;
238 Facet boolFacet;
239 if (type.Facets.TryGetValue(facetName, false, out boolFacet) && boolFacet.Value != null)
241 boolValue = (bool)boolFacet.Value;
242 return true;
245 return false;
248 internal static bool TryGetByteFacetValue(TypeUsage type, string facetName, out byte byteValue)
250 byteValue = 0;
251 Facet byteFacet;
252 if (type.Facets.TryGetValue(facetName, false, out byteFacet) && byteFacet.Value != null && !Helper.IsUnboundedFacetValue(byteFacet))
254 byteValue = (byte)byteFacet.Value;
255 return true;
258 return false;
261 internal static bool TryGetIntFacetValue(TypeUsage type, string facetName, out int intValue)
263 intValue = 0;
264 Facet intFacet;
265 if (type.Facets.TryGetValue(facetName, false, out intFacet) && intFacet.Value != null && !Helper.IsUnboundedFacetValue(intFacet) && !Helper.IsVariableFacetValue(intFacet))
267 intValue = (int)intFacet.Value;
268 return true;
271 return false;
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;
280 return 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))
291 isUnicode = false;
292 return false;
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))
309 maxLength = 0;
310 return false;
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))
321 precision = 0;
322 return false;
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))
332 scale = 0;
333 return false;
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;
344 return true;
347 typeKind = default(PrimitiveTypeKind);
348 return false;
351 #endregion
354 // Type Constructors
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));
402 /// <summary>
403 /// Creates metadata for a new row type with column names and types based on the key members of the specified Entity type
404 /// </summary>
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>>();
416 //int idx = 0;
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);
431 /// <summary>
432 /// Gets primitive type usage for <paramref name="scalarType"/>.
433 /// </summary>
434 /// <param name="scalarType">Primitive or enum type usage.</param>
435 /// <returns>
436 /// Primitive type usage for <paramref name="scalarType"/>.
437 /// </returns>
438 /// <remarks>
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.
441 /// </remarks>
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) :
449 scalarType;
452 /// <summary>
453 /// Factory method for creating a type usage for underlying type of enum type usage.
454 /// </summary>
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);
465 /// <summary>
466 /// Factory method for creating a type usage for underlying union type of spatial type usage.
467 /// </summary>
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);
477 #endregion
480 // Type extractors
482 #region Type Extractors
484 /// <summary>
485 /// Retrieves Properties and/or RelationshipEnds declared by the specified type or any base type.
486 /// </summary>
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;
507 default:
508 return EmptyArrayEdmProperty;
512 /// <summary>
513 /// Retrieves Properties and/or RelationshipEnds declared by (and ONLY by) the specified type.
514 /// </summary>
515 /// <param name="type"></param>
516 /// <returns></returns>
517 internal static IEnumerable GetDeclaredStructuralMembers(TypeUsage type)
519 return GetDeclaredStructuralMembers(type.EdmType);
522 /// <summary>
523 /// Retrieves Properties and/or RelationshipEnds declared by (and ONLY by) the specified type.
524 /// </summary>
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>();
539 default:
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;
562 default:
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);
578 return null;
581 /// <summary>
582 /// Returns row type if supplied function is a tvf returning Collection(RowType), otherwise null.
583 /// </summary>
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;
594 return null;
598 // Element type
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);
609 elementType = null;
610 return false;
613 /// <summary>
614 /// If the type refered to by the TypeUsage is a RefType, extracts the EntityType and returns true,
615 /// otherwise returns false.
616 /// </summary>
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)
622 RefType refType;
623 if (TryGetEdmType<RefType>(type, out refType) &&
624 Helper.IsEntityType(refType.ElementType))
626 referencedEntityType = (EntityType)refType.ElementType;
627 return true;
630 referencedEntityType = null;
631 return false;
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);
646 #endregion
649 // Misc
651 #region Misc
652 internal static TypeUsage GetReadOnlyType(TypeUsage type)
654 if (!(type.IsReadOnly))
656 type.SetReadOnly();
658 return type;
662 // Type Description
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);
687 else
689 return string.Format(CultureInfo.InvariantCulture, "{0}.{1}", qualifier, name);
693 /// <summary>
694 /// Converts the given CLR type into a DbType
695 /// </summary>
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))
702 case TypeCode.Empty:
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))
717 return DbType.Guid;
719 else if (clrType == typeof(System.TimeSpan))
721 return DbType.Time;
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;
734 case TypeCode.SByte:
735 return DbType.SByte;
736 case TypeCode.Byte:
737 return DbType.Byte;
738 case TypeCode.Char:
739 // Always treat char and char[] as string
740 return DbType.String;
741 case TypeCode.Int16:
742 return DbType.Int16;
743 case TypeCode.UInt16:
744 return DbType.UInt16;
745 case TypeCode.Int32:
746 return DbType.Int32;
747 case TypeCode.UInt32:
748 return DbType.UInt32;
749 case TypeCode.Int64:
750 return DbType.Int64;
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;
763 default:
764 throw EntityUtil.UnknownDataTypeCode(clrType, Type.GetTypeCode(clrType));
768 internal static bool IsIntegerConstant(TypeUsage valueType, object value, long expectedValue)
770 if (!TypeSemantics.IsIntegerNumericType(valueType))
772 return false;
775 if (null == value)
777 return false;
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);
798 default:
800 Debug.Assert(false, "Integer primitive type was not one of Byte, Int16, Int32, Int64, SByte?");
801 return false;
806 /// <summary>
807 /// returns a Typeusage
808 /// </summary>
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)
819 TypeUsage typeusage;
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});
826 break;
828 default:
829 typeusage = TypeUsage.Create(primitiveType,
830 new FacetValues{ Nullable = false });
831 break;
833 return typeusage;
836 #endregion
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;
848 #endregion