EdmProviderManifest.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Metadata / Edm / Provider / EdmProviderManifest.cs / 1 / EdmProviderManifest.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading; 

namespace System.Data.Metadata.Edm 
{ 
    internal class EdmProviderManifest : DbProviderManifest
    { 
        /// 
        /// The ConcurrencyMode Facet Name
        /// 
        internal const string ConcurrencyModeFacetName = "ConcurrencyMode"; 
        /// 
        /// The StoreGeneratedPattern Facet Name 
        ///  
        internal const string StoreGeneratedPatternFacetName = "StoreGeneratedPattern";
        private Dictionary> _facetDescriptions; 
        private System.Collections.ObjectModel.ReadOnlyCollection _primitiveTypes;
        private System.Collections.ObjectModel.ReadOnlyCollection _functions;
        private static EdmProviderManifest _instance = new EdmProviderManifest();
        private System.Collections.ObjectModel.ReadOnlyCollection[] _promotionTypes; 
        static TypeUsage[] _canonicalModelTypes;
 
        // The maximum allowed precision for decimal type in edm is 29 since clr decimal can handle upto 29 precision only 
        internal const byte MaximumDecimalPrecision = Byte.MaxValue;
        internal const byte MaximumDateTimePrecision = Byte.MaxValue; 

        /// 
        /// A private constructor to prevent other places from instantiating this class
        ///  
        private EdmProviderManifest()
        { 
        } 

        ///  
        /// Gets the EDM provider manifest singleton instance
        /// 
        internal static EdmProviderManifest Instance
        { 
            get
            { 
                return _instance; 
            }
        } 

        /// 
        /// Returns the namespace used by this provider manifest
        ///  
        public override string NamespaceName
        { 
            get { return EdmConstants.EdmNamespace; } 
        }
 
        /// 
        /// Store version hint
        /// 
        internal string Token 
        {
            // we shouldn't throw exception on properties 
            get { return String.Empty; } 
        }
 
        /// 
        /// Returns the list of all the cononical functions
        /// 
        ///  
        public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreFunctions()
        { 
            InitializeCanonicalFunctions(); 
            return _functions;
        } 

        /// 
        /// Returns all the FacetDescriptions for a particular type
        ///  
        /// the type to return FacetDescriptions for.
        /// The FacetDescriptions for the type given. 
        public override System.Collections.ObjectModel.ReadOnlyCollection GetFacetDescriptions(EdmType type) 
        {
            Debug.Assert(type is PrimitiveType, "EdmProviderManifest.GetFacetDescriptions(): Argument is not a PrimitiveType"); 

            InitializeFacetDescriptions();

            // Some types may not have facets, so just try to get them, if there aren't any, just return an empty list 
            System.Collections.ObjectModel.ReadOnlyCollection collection = null;
            if (_facetDescriptions.TryGetValue(type as PrimitiveType, out collection)) 
            { 
                return collection;
            } 
            return Helper.EmptyFacetDescriptionEnumerable;
        }

        ///  
        /// Returns a primitive type from this manifest having the specified primitive type kind
        ///  
        /// The value specifying the kind of primitive type to return 
        /// A primitive type having the given primitive type kind
        public PrimitiveType GetPrimitiveType(PrimitiveTypeKind primitiveTypeKind) 
        {
            InitializePrimitiveTypes();
            return _primitiveTypes[(int)primitiveTypeKind];
        } 

        ///  
        /// Boostrapping all the primitive types for the EDM Provider Manifest 
        /// 
        private void InitializePrimitiveTypes() 
        {
            if (_primitiveTypes != null)
            {
                return; 
            }
 
            PrimitiveType[] primitiveTypes = new PrimitiveType[EdmConstants.NumPrimitiveTypes]; 
            primitiveTypes[(int)PrimitiveTypeKind.Binary] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Boolean] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Byte] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.DateTime] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Decimal] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Double] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Single] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Guid] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Int16] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Int32] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Int64] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.SByte] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.String] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Time] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new PrimitiveType(); 

            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Binary], PrimitiveTypeKind.Binary, EdmConstants.Binary, typeof(Byte[])); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Boolean], PrimitiveTypeKind.Boolean, EdmConstants.Boolean, typeof(Boolean)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Byte], PrimitiveTypeKind.Byte, EdmConstants.Byte, typeof(Byte));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTime], PrimitiveTypeKind.DateTime, EdmConstants.DateTime, typeof(DateTime)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Decimal], PrimitiveTypeKind.Decimal, EdmConstants.Decimal, typeof(Decimal));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Double], PrimitiveTypeKind.Double, EdmConstants.Double, typeof(Double));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Single], PrimitiveTypeKind.Single, EdmConstants.Single, typeof(Single));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Guid], PrimitiveTypeKind.Guid, EdmConstants.Guid, typeof(Guid)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int16], PrimitiveTypeKind.Int16, EdmConstants.Int16, typeof(Int16));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int32], PrimitiveTypeKind.Int32, EdmConstants.Int32, typeof(Int32)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int64], PrimitiveTypeKind.Int64, EdmConstants.Int64, typeof(Int64)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.SByte], PrimitiveTypeKind.SByte, EdmConstants.SByte, typeof(SByte));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.String], PrimitiveTypeKind.String, EdmConstants.String, typeof(String)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Time], PrimitiveTypeKind.Time, EdmConstants.Time, typeof(TimeSpan));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset], PrimitiveTypeKind.DateTimeOffset, EdmConstants.DateTimeOffset, typeof(DateTimeOffset));

            // Set all primitive types to be readonly 
            foreach (PrimitiveType primitiveType in primitiveTypes)
            { 
                primitiveType.ProviderManifest = this; 
                primitiveType.SetReadOnly();
            } 

            System.Collections.ObjectModel.ReadOnlyCollection readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection(primitiveTypes);

            // Set the result to _primitiveTypes at the end 
            Interlocked.CompareExchange>(ref _primitiveTypes, readOnlyTypes, null);
        } 
 
        /// 
        /// Initialize all the primitive type with the given primitive type kind and name 
        /// 
        /// The primitive type to initialize
        /// Type of the primitive type which is getting initialized
        /// name of the built in type 
        /// the CLR Type of that maps to the EDM PrimitiveType
        private void InitializePrimitiveType(PrimitiveType primitiveType, 
                                             PrimitiveTypeKind primitiveTypeKind, 
                                             string name,
                                             Type clrType) 
        {
            // Only null types are not abstract and they are sealed, all others are abstract and unsealed
            EdmType.Initialize(primitiveType, name,
                               EdmConstants.EdmNamespace, 
                               DataSpace.CSpace,
                               true /* isabstract */, 
                               null /* baseType */); 
            PrimitiveType.Initialize(primitiveType,
                                     primitiveTypeKind, 
                                     true, // isDefault
                                     this);
            Debug.Assert(clrType == primitiveType.ClrEquivalentType, "ClrEquivalentType mismatch");
        } 

        ///  
        /// Boostrapping all the facet descriptions for the EDM Provider Manifest 
        /// 
        private void InitializeFacetDescriptions() 
        {
            if (_facetDescriptions != null)
            {
                return; 
            }
 
            // Ensure the primitive types are there 
            InitializePrimitiveTypes();
 
            // Create the dictionary of facet descriptions
            Dictionary> facetDescriptions = new Dictionary>();

            // String facets 
            FacetDescription[] list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.String);
            PrimitiveType applicableType = _primitiveTypes[(int)PrimitiveTypeKind.String]; 
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 

            // Binary facets 
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Binary);
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Binary];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
 
            // DateTime facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTime); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTime]; 
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
 
            // Time facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Time);
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Time];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 

            // DateTimeOffset facets 
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTimeOffset); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 


            // Decimal facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Decimal); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Decimal];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 
 
            // Set the result to _facetDescriptions at the end
            Interlocked.CompareExchange>>(ref _facetDescriptions, 
                                                                                                         facetDescriptions,
                                                                                                         null);
        }
 
        internal static FacetDescription[] GetInitialFacetDescriptions(PrimitiveTypeKind primitiveTypeKind)
        { 
            FacetDescription[] list; 

            switch (primitiveTypeKind) 
            {
                case PrimitiveTypeKind.String:
                    {
                        list = new FacetDescription[3]; 

                        list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32), 
                                                      0,
                                                      Int32.MaxValue, 
                                                      null));
                        list[1] = (new FacetDescription(DbProviderManifest.UnicodeFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null)); 
                        list[2] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null));

                        return list; 
                    }
 
                case PrimitiveTypeKind.Binary: 
                    {
                        list = new FacetDescription[2]; 

                        list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
                                                      0, 
                                                      Int32.MaxValue,
                                                      null)); 
                        list[1] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null));
                        return list;
                    } 

                case PrimitiveTypeKind.DateTime: 
                    { 
                        list = new FacetDescription[1];
 
                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, null));
 
                        return list;
                    } 
                case PrimitiveTypeKind.Time: 
                    {
                        list = new FacetDescription[1]; 

                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue)); 

                        return list; 
                    } 
                case PrimitiveTypeKind.DateTimeOffset:
                    { 
                        list = new FacetDescription[1];
                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue)); 

                        return list; 
                    } 
                case PrimitiveTypeKind.Decimal:
                    { 
                        list = new FacetDescription[2];

                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte), 
                                                      1,
                                                      EdmProviderManifest.MaximumDecimalPrecision, 
                                                      null)); 
                        list[1] = (new FacetDescription(DbProviderManifest.ScaleFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte), 
                                                      0,
                                                      EdmProviderManifest.MaximumDecimalPrecision,
                                                      null));
                        return list; 
                    }
 
                default: 
                    return null;
            } 
        }

        /// 
        /// Boostrapping all the canonical functions for the EDM Provider Manifest 
        /// 
        private void InitializeCanonicalFunctions() 
        { 
            if (_functions != null)
            { 
                return;
            }

            List functions = new List(); 

            // Initialize all the various parameter types. We do not want to create new instance of parameter types 
            // again and again for perf reasons 
            TypeUsage[] parameterTypeUsages = new TypeUsage[EdmConstants.NumPrimitiveTypes];
            Func CreateFirstParameter = ptk => new FunctionParameter("arg1", parameterTypeUsages[(int)ptk], ParameterMode.In); 
            Func CreateSecondParameter = ptk => new FunctionParameter("arg2", parameterTypeUsages[(int)ptk], ParameterMode.In);
            Func CreateThirdParameter = ptk => new FunctionParameter("arg3", parameterTypeUsages[(int)ptk], ParameterMode.In);
            Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
            Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("arg1", TypeUsage.Create(parameterTypeUsages[(int)ptk].EdmType.GetCollectionType()), ParameterMode.In); 
            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
            { 
                parameterTypeUsages[i] = TypeUsage.Create(_primitiveTypes[i]); 
            }
 
            #region Aggregate Functions

            // function overloads for Max, Min and Sum
            string[] functionNames = { "Max", "Min" }; 
            PrimitiveTypeKind[] parameterTypes = { PrimitiveTypeKind.Byte,
                                     PrimitiveTypeKind.DateTime, 
                                     PrimitiveTypeKind.Decimal, 
                                     PrimitiveTypeKind.Double,
                                     PrimitiveTypeKind.Int16, 
                                     PrimitiveTypeKind.Int32,
                                     PrimitiveTypeKind.Int64,
                                     PrimitiveTypeKind.SByte,
                                     PrimitiveTypeKind.Single, 
                                     PrimitiveTypeKind.String,
                                     PrimitiveTypeKind.Binary, 
                                     PrimitiveTypeKind.Time, 
                                     PrimitiveTypeKind.DateTimeOffset
                                   }; 

            foreach (string functionName in functionNames)
            {
                foreach (PrimitiveTypeKind kind in parameterTypes) 
                {
                    EdmFunction function = CreateAggregateCannonicalFunction( functionName, 
                                                            CreateReturnParameter(kind), 
                                                            CreateFirstParametersCollectionType(kind));
                    functions.Add(function); 
                }
            }

            string[] functionNames1 = { "Avg", "Sum" }; 

            PrimitiveTypeKind[] aggregateParameterTypes = { PrimitiveTypeKind.Decimal, 
                                              PrimitiveTypeKind.Double, 
                                              PrimitiveTypeKind.Int32,
                                              PrimitiveTypeKind.Int64 }; 

            foreach (string functionName in functionNames1)
            {
                foreach (PrimitiveTypeKind kind in aggregateParameterTypes) 
                {
                    EdmFunction function = CreateAggregateCannonicalFunction(functionName, 
                                                           CreateReturnParameter(kind), 
                                                           CreateFirstParametersCollectionType(kind));
                    functions.Add(function); 
                }
            }

            // STDEV 
            {
                string stDevFunctioName = "StDev"; 
                PrimitiveTypeKind[] stDevParameterTypes = { PrimitiveTypeKind.Decimal, 
                                              PrimitiveTypeKind.Double,
                                              PrimitiveTypeKind.Int32, 
                                              PrimitiveTypeKind.Int64};
                foreach (PrimitiveTypeKind kind in stDevParameterTypes)
                {
                    EdmFunction function = CreateAggregateCannonicalFunction( stDevFunctioName, 
                                                            CreateReturnParameter(PrimitiveTypeKind.Double),
                                                            CreateFirstParametersCollectionType(kind)); 
                    functions.Add(function); 
                }
            } 


            // Count and Big Count must be supported for all edm types
            for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++) 
            {
                PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex; 
                EdmFunction function = CreateAggregateCannonicalFunction("Count", 
                                                        CreateReturnParameter(PrimitiveTypeKind.Int32),
                                                        CreateFirstParametersCollectionType(kind)); 
                functions.Add(function);
            }

            for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++) 
            {
                PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex; 
                EdmFunction function = CreateAggregateCannonicalFunction("BigCount", 
                                                        CreateReturnParameter(PrimitiveTypeKind.Int64),
                                                        CreateFirstParametersCollectionType(kind)); 
                functions.Add(function);
            }
            #endregion
 
            #region String Functions
 
            functions.Add(CreateCannonicalFunction("Trim", 
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("RTrim",
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("LTrim", 
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            functions.Add(CreateCannonicalFunction("Concat",
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("Length", 
                                          CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            // Substring, Left, Right overloads and also for DateAdd function
            PrimitiveTypeKind[] subStringParameterTypes = { PrimitiveTypeKind.Byte,
                                              PrimitiveTypeKind.Int16,
                                              PrimitiveTypeKind.Int32, 
                                              PrimitiveTypeKind.Int64,
                                              PrimitiveTypeKind.SByte }; 
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Substring",
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind), 
                                              CreateThirdParameter(kind)));
            } 
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Left",
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind))); 
            }
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes) 
            {
                functions.Add(CreateCannonicalFunction("Right", 
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind)));
            } 

            functions.Add(CreateCannonicalFunction("Replace", 
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String), 
                                          CreateThirdParameter(PrimitiveTypeKind.String)));

            functions.Add(CreateCannonicalFunction("IndexOf",
                                          CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String))); 
 
            functions.Add(CreateCannonicalFunction("ToUpper",
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));

            functions.Add(CreateCannonicalFunction("ToLower",
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            functions.Add(CreateCannonicalFunction("Reverse", 
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 
            #endregion // String Functions

            #region DateTime Functions
            string[] dateTimeFunctions = { "Year", "Month", "Day" }; 

            PrimitiveTypeKind[] dateTimeParameterTypes = { PrimitiveTypeKind.DateTimeOffset, 
                                             PrimitiveTypeKind.DateTime, 
                                           };
            foreach (string dateTimeFunction in dateTimeFunctions) 
            {
                foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
                {
                    functions.Add(CreateCannonicalFunction(dateTimeFunction, 
                                                  CreateReturnParameter(PrimitiveTypeKind.Int32),
                                                  CreateFirstParameter(kind))); 
                } 
            }
 
            string[] timeFunctions = { "Hour", "Minute", "Second", "Millisecond" };

            PrimitiveTypeKind[] timeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
                                         PrimitiveTypeKind.DateTime, 
                                         PrimitiveTypeKind.Time,
                                       }; 
            foreach (string timeFunction in timeFunctions) 
            {
                foreach (PrimitiveTypeKind kind in timeParameterTypes) 
                {
                    functions.Add(CreateCannonicalFunction(timeFunction,
                                          CreateReturnParameter(PrimitiveTypeKind.Int32),
                                          CreateFirstParameter(kind))); 
                }
            } 
 

            EdmFunction dateFunction = CreateCannonicalFunction("CurrentDateTime", 
                                                                 CreateReturnParameter(PrimitiveTypeKind.DateTime));
            functions.Add(dateFunction);

            EdmFunction dateTimeOffsetFunction = CreateCannonicalFunction("CurrentDateTimeOffset", 
                                           CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset));
            functions.Add(dateTimeOffsetFunction); 
 
            functions.Add(CreateCannonicalFunction("GetTotalOffsetMinutes",
                                                  CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                                  CreateFirstParameter(PrimitiveTypeKind.DateTimeOffset)));

            dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
                               CreateReturnParameter(PrimitiveTypeKind.DateTime)); 
            functions.Add(dateFunction);
            #endregion // DateTime Functions 
            #region Math Functions 

            string[] mathFunctions = { "Round", "Floor", "Ceiling" }; 

            // Overloads for ROUND, FLOOR, CEILING functions
            PrimitiveTypeKind[] roundParameterTypes = { PrimitiveTypeKind.Single,
                                          PrimitiveTypeKind.Double, 
                                          PrimitiveTypeKind.Decimal };
 
            foreach (string functionName in mathFunctions) 
            {
                foreach (PrimitiveTypeKind kind in roundParameterTypes) 
                {
                    functions.Add(CreateCannonicalFunction(functionName,
                                                  CreateReturnParameter(kind),
                                                  CreateFirstParameter(kind))); 
                }
            } 
 
            // Overloads for ABS functions
            PrimitiveTypeKind[] absParameterTypes = { PrimitiveTypeKind.Decimal, 
                                        PrimitiveTypeKind.Double,
                                        PrimitiveTypeKind.Int16,
                                        PrimitiveTypeKind.Int32,
                                        PrimitiveTypeKind.Int64, 
                                        PrimitiveTypeKind.Byte,
                                        PrimitiveTypeKind.Single }; 
 
            foreach (PrimitiveTypeKind kind in absParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Abs",
                                              CreateReturnParameter(kind),
                                              CreateFirstParameter(kind)));
            } 
            #endregion // Math Functions
 
            #region Bitwise Functions 

            string[] bitwiseFunctions = { "BitwiseAnd", "BitwiseOr", "BitwiseXor" }; 

            // Overloads for BitwiseAND, BitwiseNOT, BitwiseOR, BitwiseXOR functions
            PrimitiveTypeKind[] bitwiseFunctionOverloads = { PrimitiveTypeKind.Int16,
                                               PrimitiveTypeKind.Int32, 
                                               PrimitiveTypeKind.Int64,
                                               PrimitiveTypeKind.Byte }; 
 
            foreach (string functionName in bitwiseFunctions)
            { 
                foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
                {
                    functions.Add(CreateCannonicalFunction(functionName,
                                                  CreateReturnParameter(kind), 
                                                  CreateFirstParameter(kind),
                                                  CreateSecondParameter(kind))); 
                } 
            }
 
            foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
            {
                functions.Add(CreateCannonicalFunction("BitwiseNot",
                                              CreateReturnParameter(kind), 
                                              CreateFirstParameter(kind)));
            } 
            #endregion 

            #region Misc Functions 
            functions.Add(CreateCannonicalFunction("NewGuid",
                                          CreateReturnParameter(PrimitiveTypeKind.Guid)));
            #endregion // Misc Functions
 
            //Set all the functions to readonly
            foreach (EdmFunction function in functions) 
            { 
                function.SetReadOnly();
            } 

            System.Collections.ObjectModel.ReadOnlyCollection readOnlyFunctions = new System.Collections.ObjectModel.ReadOnlyCollection(functions);

            Interlocked.CompareExchange>(ref _functions, readOnlyFunctions, null); 
        }
 
        private static EdmFunction CreateAggregateCannonicalFunction(string name, FunctionParameter returnParameter, FunctionParameter parameter) 
        {
            Debug.Assert(name != null && returnParameter != null && parameter != null, "did you choose the wrong overload"); 

            EdmFunction function = new EdmFunction( name,
                EdmConstants.CanonicalFunctionNamespace,
                DataSpace.CSpace, 
                new EdmFunctionPayload
                { 
                    IsAggregate = true, 
                    IsBuiltIn = true,
                    ReturnParameter = returnParameter, 
                    Parameters = new FunctionParameter[1] { parameter },
                });
            return function;
 
        }
 
        private static EdmFunction CreateCannonicalFunction(string name, FunctionParameter returnParameter, params FunctionParameter []  parameters) 
        {
            Debug.Assert(name != null && returnParameter != null && parameters != null, "did you choose the wrong overload"); 

            EdmFunction function = new EdmFunction(name,
                EdmConstants.CanonicalFunctionNamespace,
                DataSpace.CSpace, 
                new EdmFunctionPayload
                { 
                    IsBuiltIn = true, 
                    ReturnParameter = returnParameter,
                    Parameters = parameters, 
                });
            return function;

        } 

        #region Edm Provider Specific Functionality 
        ///  
        /// Returns the list of super-types for the given primitiveType
        ///  
        /// 
        /// 
        internal System.Collections.ObjectModel.ReadOnlyCollection GetPromotionTypes(PrimitiveType primitiveType)
        { 
            InitializePromotableTypes();
 
            return _promotionTypes[(int)primitiveType.PrimitiveTypeKind]; 
        }
 
        /// 
        /// Initializes Promotion Type relation
        /// 
        private void InitializePromotableTypes() 
        {
            if (null != _promotionTypes) 
            { 
                return;
            } 

            System.Collections.ObjectModel.ReadOnlyCollection[] promotionTypes = new System.Collections.ObjectModel.ReadOnlyCollection[EdmConstants.NumPrimitiveTypes];

            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++) 
            {
                promotionTypes[i] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { _primitiveTypes[i] }); 
            } 

            // 
            // PrimitiveTypeKind.Byte
            //
            promotionTypes[(int)PrimitiveTypeKind.Byte] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Byte], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int16],
                _primitiveTypes[(int)PrimitiveTypeKind.Int32], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int64], 
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single], 
                _primitiveTypes[(int)PrimitiveTypeKind.Double]
            });

            // 
            // PrimitiveTypeKind.Int16
            // 
            promotionTypes[(int)PrimitiveTypeKind.Int16] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { 
                _primitiveTypes[(int)PrimitiveTypeKind.Int16],
                _primitiveTypes[(int)PrimitiveTypeKind.Int32], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int64],
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single],
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 
            // 
            // PrimitiveTypeKind.Int32
            // 
            promotionTypes[(int)PrimitiveTypeKind.Int32] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Int32],
                _primitiveTypes[(int)PrimitiveTypeKind.Int64],
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal], 
                _primitiveTypes[(int)PrimitiveTypeKind.Single],
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            }); 

            // 
            // PrimitiveTypeKind.Int64
            //
            promotionTypes[(int)PrimitiveTypeKind.Int64] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Int64], 
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single], 
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 

            //
            // PrimitiveTypeKind.Decimal
            // 
            promotionTypes[(int)PrimitiveTypeKind.Decimal] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal] 
            }); 

            // 
            // PrimitiveTypeKind.Single
            //
            promotionTypes[(int)PrimitiveTypeKind.Single] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 
            // 
            // PrimitiveTypeKind.DateTime
            // 
            promotionTypes[(int)PrimitiveTypeKind.DateTime] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.DateTime]
            });
 
            //
            // PrimitiveTypeKind.Time 
            // 
            promotionTypes[(int)PrimitiveTypeKind.Time] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Time] 
            });

            //
            // PrimitiveTypeKind.DateTimeOffset 
            //
            promotionTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { 
                _primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] 
            });
 
            Interlocked.CompareExchange[]>(ref _promotionTypes,
                                                                             promotionTypes,
                                                                             null);
        } 

        internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind) 
        { 
            if (null == _canonicalModelTypes)
            { 
                InitializeCanonicalModelTypes();
            }
            return _canonicalModelTypes[(int)primitiveTypeKind];
        } 

        ///  
        /// Initializes Canonical Model Types 
        /// 
        private void InitializeCanonicalModelTypes() 
        {
            TypeUsage[] canonicalTypes = new TypeUsage[EdmConstants.NumPrimitiveTypes];
            for (int primitiveTypeIndex = 0; primitiveTypeIndex < EdmConstants.NumPrimitiveTypes; primitiveTypeIndex++)
            { 
                PrimitiveType primitiveType = _primitiveTypes[primitiveTypeIndex];
                TypeUsage typeUsage = TypeUsage.CreateDefaultTypeUsage(primitiveType); 
                Debug.Assert(null != typeUsage, "TypeUsage must not be null"); 
                canonicalTypes[primitiveTypeIndex] = typeUsage;
            } 

            Interlocked.CompareExchange(ref _canonicalModelTypes, canonicalTypes, null);
        }
        #endregion 

        #region DbProviderManifest Interface 
        ///  
        /// Returns all the primitive types supported by the provider manifest
        ///  
        /// A collection of primitive types
        public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreTypes()
        {
            InitializePrimitiveTypes(); 
            return _primitiveTypes;
        } 
 
        public override TypeUsage GetEdmType(TypeUsage storeType)
        { 
            throw new NotImplementedException();
        }

        public override TypeUsage GetStoreType(TypeUsage edmType) 
        {
            throw new NotImplementedException(); 
        } 

        internal TypeUsage ForgetScalarConstraints(TypeUsage type) 
        {
            PrimitiveType primitiveType = type.EdmType as PrimitiveType;
            Debug.Assert(primitiveType != null, "type argument must be primitive in order to use this function");
            if (primitiveType != null) 
            {
                return GetCanonicalModelTypeUsage(primitiveType.PrimitiveTypeKind); 
            } 
            else
            { 
                return type;
            }
        }
 
        /// 
        /// Providers should override this to return information specific to their provider. 
        /// 
        /// This method should never return null.
        ///  
        /// The name of the information to be retrieved.
        /// An XmlReader at the begining of the information requested.
        protected override System.Xml.XmlReader GetDbInformation(string informationType)
        { 
            throw new NotImplementedException();
        } 
        #endregion 

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System.Data.Common; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading; 

namespace System.Data.Metadata.Edm 
{ 
    internal class EdmProviderManifest : DbProviderManifest
    { 
        /// 
        /// The ConcurrencyMode Facet Name
        /// 
        internal const string ConcurrencyModeFacetName = "ConcurrencyMode"; 
        /// 
        /// The StoreGeneratedPattern Facet Name 
        ///  
        internal const string StoreGeneratedPatternFacetName = "StoreGeneratedPattern";
        private Dictionary> _facetDescriptions; 
        private System.Collections.ObjectModel.ReadOnlyCollection _primitiveTypes;
        private System.Collections.ObjectModel.ReadOnlyCollection _functions;
        private static EdmProviderManifest _instance = new EdmProviderManifest();
        private System.Collections.ObjectModel.ReadOnlyCollection[] _promotionTypes; 
        static TypeUsage[] _canonicalModelTypes;
 
        // The maximum allowed precision for decimal type in edm is 29 since clr decimal can handle upto 29 precision only 
        internal const byte MaximumDecimalPrecision = Byte.MaxValue;
        internal const byte MaximumDateTimePrecision = Byte.MaxValue; 

        /// 
        /// A private constructor to prevent other places from instantiating this class
        ///  
        private EdmProviderManifest()
        { 
        } 

        ///  
        /// Gets the EDM provider manifest singleton instance
        /// 
        internal static EdmProviderManifest Instance
        { 
            get
            { 
                return _instance; 
            }
        } 

        /// 
        /// Returns the namespace used by this provider manifest
        ///  
        public override string NamespaceName
        { 
            get { return EdmConstants.EdmNamespace; } 
        }
 
        /// 
        /// Store version hint
        /// 
        internal string Token 
        {
            // we shouldn't throw exception on properties 
            get { return String.Empty; } 
        }
 
        /// 
        /// Returns the list of all the cononical functions
        /// 
        ///  
        public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreFunctions()
        { 
            InitializeCanonicalFunctions(); 
            return _functions;
        } 

        /// 
        /// Returns all the FacetDescriptions for a particular type
        ///  
        /// the type to return FacetDescriptions for.
        /// The FacetDescriptions for the type given. 
        public override System.Collections.ObjectModel.ReadOnlyCollection GetFacetDescriptions(EdmType type) 
        {
            Debug.Assert(type is PrimitiveType, "EdmProviderManifest.GetFacetDescriptions(): Argument is not a PrimitiveType"); 

            InitializeFacetDescriptions();

            // Some types may not have facets, so just try to get them, if there aren't any, just return an empty list 
            System.Collections.ObjectModel.ReadOnlyCollection collection = null;
            if (_facetDescriptions.TryGetValue(type as PrimitiveType, out collection)) 
            { 
                return collection;
            } 
            return Helper.EmptyFacetDescriptionEnumerable;
        }

        ///  
        /// Returns a primitive type from this manifest having the specified primitive type kind
        ///  
        /// The value specifying the kind of primitive type to return 
        /// A primitive type having the given primitive type kind
        public PrimitiveType GetPrimitiveType(PrimitiveTypeKind primitiveTypeKind) 
        {
            InitializePrimitiveTypes();
            return _primitiveTypes[(int)primitiveTypeKind];
        } 

        ///  
        /// Boostrapping all the primitive types for the EDM Provider Manifest 
        /// 
        private void InitializePrimitiveTypes() 
        {
            if (_primitiveTypes != null)
            {
                return; 
            }
 
            PrimitiveType[] primitiveTypes = new PrimitiveType[EdmConstants.NumPrimitiveTypes]; 
            primitiveTypes[(int)PrimitiveTypeKind.Binary] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Boolean] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Byte] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.DateTime] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Decimal] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Double] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Single] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Guid] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Int16] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.Int32] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Int64] = new PrimitiveType(); 
            primitiveTypes[(int)PrimitiveTypeKind.SByte] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.String] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.Time] = new PrimitiveType();
            primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new PrimitiveType(); 

            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Binary], PrimitiveTypeKind.Binary, EdmConstants.Binary, typeof(Byte[])); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Boolean], PrimitiveTypeKind.Boolean, EdmConstants.Boolean, typeof(Boolean)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Byte], PrimitiveTypeKind.Byte, EdmConstants.Byte, typeof(Byte));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTime], PrimitiveTypeKind.DateTime, EdmConstants.DateTime, typeof(DateTime)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Decimal], PrimitiveTypeKind.Decimal, EdmConstants.Decimal, typeof(Decimal));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Double], PrimitiveTypeKind.Double, EdmConstants.Double, typeof(Double));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Single], PrimitiveTypeKind.Single, EdmConstants.Single, typeof(Single));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Guid], PrimitiveTypeKind.Guid, EdmConstants.Guid, typeof(Guid)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int16], PrimitiveTypeKind.Int16, EdmConstants.Int16, typeof(Int16));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int32], PrimitiveTypeKind.Int32, EdmConstants.Int32, typeof(Int32)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Int64], PrimitiveTypeKind.Int64, EdmConstants.Int64, typeof(Int64)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.SByte], PrimitiveTypeKind.SByte, EdmConstants.SByte, typeof(SByte));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.String], PrimitiveTypeKind.String, EdmConstants.String, typeof(String)); 
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.Time], PrimitiveTypeKind.Time, EdmConstants.Time, typeof(TimeSpan));
            InitializePrimitiveType(primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset], PrimitiveTypeKind.DateTimeOffset, EdmConstants.DateTimeOffset, typeof(DateTimeOffset));

            // Set all primitive types to be readonly 
            foreach (PrimitiveType primitiveType in primitiveTypes)
            { 
                primitiveType.ProviderManifest = this; 
                primitiveType.SetReadOnly();
            } 

            System.Collections.ObjectModel.ReadOnlyCollection readOnlyTypes = new System.Collections.ObjectModel.ReadOnlyCollection(primitiveTypes);

            // Set the result to _primitiveTypes at the end 
            Interlocked.CompareExchange>(ref _primitiveTypes, readOnlyTypes, null);
        } 
 
        /// 
        /// Initialize all the primitive type with the given primitive type kind and name 
        /// 
        /// The primitive type to initialize
        /// Type of the primitive type which is getting initialized
        /// name of the built in type 
        /// the CLR Type of that maps to the EDM PrimitiveType
        private void InitializePrimitiveType(PrimitiveType primitiveType, 
                                             PrimitiveTypeKind primitiveTypeKind, 
                                             string name,
                                             Type clrType) 
        {
            // Only null types are not abstract and they are sealed, all others are abstract and unsealed
            EdmType.Initialize(primitiveType, name,
                               EdmConstants.EdmNamespace, 
                               DataSpace.CSpace,
                               true /* isabstract */, 
                               null /* baseType */); 
            PrimitiveType.Initialize(primitiveType,
                                     primitiveTypeKind, 
                                     true, // isDefault
                                     this);
            Debug.Assert(clrType == primitiveType.ClrEquivalentType, "ClrEquivalentType mismatch");
        } 

        ///  
        /// Boostrapping all the facet descriptions for the EDM Provider Manifest 
        /// 
        private void InitializeFacetDescriptions() 
        {
            if (_facetDescriptions != null)
            {
                return; 
            }
 
            // Ensure the primitive types are there 
            InitializePrimitiveTypes();
 
            // Create the dictionary of facet descriptions
            Dictionary> facetDescriptions = new Dictionary>();

            // String facets 
            FacetDescription[] list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.String);
            PrimitiveType applicableType = _primitiveTypes[(int)PrimitiveTypeKind.String]; 
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 

            // Binary facets 
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Binary);
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Binary];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
 
            // DateTime facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTime); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTime]; 
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list));
 
            // Time facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Time);
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Time];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 

            // DateTimeOffset facets 
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.DateTimeOffset); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 


            // Decimal facets
            list = EdmProviderManifest.GetInitialFacetDescriptions(PrimitiveTypeKind.Decimal); 
            applicableType = _primitiveTypes[(int)PrimitiveTypeKind.Decimal];
            facetDescriptions.Add(applicableType, Array.AsReadOnly(list)); 
 
            // Set the result to _facetDescriptions at the end
            Interlocked.CompareExchange>>(ref _facetDescriptions, 
                                                                                                         facetDescriptions,
                                                                                                         null);
        }
 
        internal static FacetDescription[] GetInitialFacetDescriptions(PrimitiveTypeKind primitiveTypeKind)
        { 
            FacetDescription[] list; 

            switch (primitiveTypeKind) 
            {
                case PrimitiveTypeKind.String:
                    {
                        list = new FacetDescription[3]; 

                        list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32), 
                                                      0,
                                                      Int32.MaxValue, 
                                                      null));
                        list[1] = (new FacetDescription(DbProviderManifest.UnicodeFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null)); 
                        list[2] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null));

                        return list; 
                    }
 
                case PrimitiveTypeKind.Binary: 
                    {
                        list = new FacetDescription[2]; 

                        list[0] = (new FacetDescription(DbProviderManifest.MaxLengthFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Int32),
                                                      0, 
                                                      Int32.MaxValue,
                                                      null)); 
                        list[1] = (new FacetDescription(DbProviderManifest.FixedLengthFacetName, 
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Boolean),
                                                      null, 
                                                      null,
                                                      null));
                        return list;
                    } 

                case PrimitiveTypeKind.DateTime: 
                    { 
                        list = new FacetDescription[1];
 
                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, null));
 
                        return list;
                    } 
                case PrimitiveTypeKind.Time: 
                    {
                        list = new FacetDescription[1]; 

                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue)); 

                        return list; 
                    } 
                case PrimitiveTypeKind.DateTimeOffset:
                    { 
                        list = new FacetDescription[1];
                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                              MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte),
                              0, EdmProviderManifest.MaximumDateTimePrecision, TypeUsage.DefaultDateTimePrecisionFacetValue)); 

                        return list; 
                    } 
                case PrimitiveTypeKind.Decimal:
                    { 
                        list = new FacetDescription[2];

                        list[0] = (new FacetDescription(DbProviderManifest.PrecisionFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte), 
                                                      1,
                                                      EdmProviderManifest.MaximumDecimalPrecision, 
                                                      null)); 
                        list[1] = (new FacetDescription(DbProviderManifest.ScaleFacetName,
                                                      MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.Byte), 
                                                      0,
                                                      EdmProviderManifest.MaximumDecimalPrecision,
                                                      null));
                        return list; 
                    }
 
                default: 
                    return null;
            } 
        }

        /// 
        /// Boostrapping all the canonical functions for the EDM Provider Manifest 
        /// 
        private void InitializeCanonicalFunctions() 
        { 
            if (_functions != null)
            { 
                return;
            }

            List functions = new List(); 

            // Initialize all the various parameter types. We do not want to create new instance of parameter types 
            // again and again for perf reasons 
            TypeUsage[] parameterTypeUsages = new TypeUsage[EdmConstants.NumPrimitiveTypes];
            Func CreateFirstParameter = ptk => new FunctionParameter("arg1", parameterTypeUsages[(int)ptk], ParameterMode.In); 
            Func CreateSecondParameter = ptk => new FunctionParameter("arg2", parameterTypeUsages[(int)ptk], ParameterMode.In);
            Func CreateThirdParameter = ptk => new FunctionParameter("arg3", parameterTypeUsages[(int)ptk], ParameterMode.In);
            Func CreateReturnParameter = ptk => new FunctionParameter(EdmConstants.ReturnType, parameterTypeUsages[(int)ptk], ParameterMode.ReturnValue);
            Func CreateFirstParametersCollectionType = ptk => new FunctionParameter("arg1", TypeUsage.Create(parameterTypeUsages[(int)ptk].EdmType.GetCollectionType()), ParameterMode.In); 
            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++)
            { 
                parameterTypeUsages[i] = TypeUsage.Create(_primitiveTypes[i]); 
            }
 
            #region Aggregate Functions

            // function overloads for Max, Min and Sum
            string[] functionNames = { "Max", "Min" }; 
            PrimitiveTypeKind[] parameterTypes = { PrimitiveTypeKind.Byte,
                                     PrimitiveTypeKind.DateTime, 
                                     PrimitiveTypeKind.Decimal, 
                                     PrimitiveTypeKind.Double,
                                     PrimitiveTypeKind.Int16, 
                                     PrimitiveTypeKind.Int32,
                                     PrimitiveTypeKind.Int64,
                                     PrimitiveTypeKind.SByte,
                                     PrimitiveTypeKind.Single, 
                                     PrimitiveTypeKind.String,
                                     PrimitiveTypeKind.Binary, 
                                     PrimitiveTypeKind.Time, 
                                     PrimitiveTypeKind.DateTimeOffset
                                   }; 

            foreach (string functionName in functionNames)
            {
                foreach (PrimitiveTypeKind kind in parameterTypes) 
                {
                    EdmFunction function = CreateAggregateCannonicalFunction( functionName, 
                                                            CreateReturnParameter(kind), 
                                                            CreateFirstParametersCollectionType(kind));
                    functions.Add(function); 
                }
            }

            string[] functionNames1 = { "Avg", "Sum" }; 

            PrimitiveTypeKind[] aggregateParameterTypes = { PrimitiveTypeKind.Decimal, 
                                              PrimitiveTypeKind.Double, 
                                              PrimitiveTypeKind.Int32,
                                              PrimitiveTypeKind.Int64 }; 

            foreach (string functionName in functionNames1)
            {
                foreach (PrimitiveTypeKind kind in aggregateParameterTypes) 
                {
                    EdmFunction function = CreateAggregateCannonicalFunction(functionName, 
                                                           CreateReturnParameter(kind), 
                                                           CreateFirstParametersCollectionType(kind));
                    functions.Add(function); 
                }
            }

            // STDEV 
            {
                string stDevFunctioName = "StDev"; 
                PrimitiveTypeKind[] stDevParameterTypes = { PrimitiveTypeKind.Decimal, 
                                              PrimitiveTypeKind.Double,
                                              PrimitiveTypeKind.Int32, 
                                              PrimitiveTypeKind.Int64};
                foreach (PrimitiveTypeKind kind in stDevParameterTypes)
                {
                    EdmFunction function = CreateAggregateCannonicalFunction( stDevFunctioName, 
                                                            CreateReturnParameter(PrimitiveTypeKind.Double),
                                                            CreateFirstParametersCollectionType(kind)); 
                    functions.Add(function); 
                }
            } 


            // Count and Big Count must be supported for all edm types
            for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++) 
            {
                PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex; 
                EdmFunction function = CreateAggregateCannonicalFunction("Count", 
                                                        CreateReturnParameter(PrimitiveTypeKind.Int32),
                                                        CreateFirstParametersCollectionType(kind)); 
                functions.Add(function);
            }

            for (int kindIndex = 0; kindIndex < EdmConstants.NumPrimitiveTypes; kindIndex++) 
            {
                PrimitiveTypeKind kind = (PrimitiveTypeKind)kindIndex; 
                EdmFunction function = CreateAggregateCannonicalFunction("BigCount", 
                                                        CreateReturnParameter(PrimitiveTypeKind.Int64),
                                                        CreateFirstParametersCollectionType(kind)); 
                functions.Add(function);
            }
            #endregion
 
            #region String Functions
 
            functions.Add(CreateCannonicalFunction("Trim", 
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("RTrim",
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("LTrim", 
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            functions.Add(CreateCannonicalFunction("Concat",
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String))); 

            functions.Add(CreateCannonicalFunction("Length", 
                                          CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            // Substring, Left, Right overloads and also for DateAdd function
            PrimitiveTypeKind[] subStringParameterTypes = { PrimitiveTypeKind.Byte,
                                              PrimitiveTypeKind.Int16,
                                              PrimitiveTypeKind.Int32, 
                                              PrimitiveTypeKind.Int64,
                                              PrimitiveTypeKind.SByte }; 
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Substring",
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind), 
                                              CreateThirdParameter(kind)));
            } 
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Left",
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind))); 
            }
 
            foreach (PrimitiveTypeKind kind in subStringParameterTypes) 
            {
                functions.Add(CreateCannonicalFunction("Right", 
                                              CreateReturnParameter(PrimitiveTypeKind.String),
                                              CreateFirstParameter(PrimitiveTypeKind.String),
                                              CreateSecondParameter(kind)));
            } 

            functions.Add(CreateCannonicalFunction("Replace", 
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String), 
                                          CreateThirdParameter(PrimitiveTypeKind.String)));

            functions.Add(CreateCannonicalFunction("IndexOf",
                                          CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                          CreateFirstParameter(PrimitiveTypeKind.String),
                                          CreateSecondParameter(PrimitiveTypeKind.String))); 
 
            functions.Add(CreateCannonicalFunction("ToUpper",
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));

            functions.Add(CreateCannonicalFunction("ToLower",
                                          CreateReturnParameter(PrimitiveTypeKind.String), 
                                          CreateFirstParameter(PrimitiveTypeKind.String)));
 
            functions.Add(CreateCannonicalFunction("Reverse", 
                                          CreateReturnParameter(PrimitiveTypeKind.String),
                                          CreateFirstParameter(PrimitiveTypeKind.String))); 
            #endregion // String Functions

            #region DateTime Functions
            string[] dateTimeFunctions = { "Year", "Month", "Day" }; 

            PrimitiveTypeKind[] dateTimeParameterTypes = { PrimitiveTypeKind.DateTimeOffset, 
                                             PrimitiveTypeKind.DateTime, 
                                           };
            foreach (string dateTimeFunction in dateTimeFunctions) 
            {
                foreach (PrimitiveTypeKind kind in dateTimeParameterTypes)
                {
                    functions.Add(CreateCannonicalFunction(dateTimeFunction, 
                                                  CreateReturnParameter(PrimitiveTypeKind.Int32),
                                                  CreateFirstParameter(kind))); 
                } 
            }
 
            string[] timeFunctions = { "Hour", "Minute", "Second", "Millisecond" };

            PrimitiveTypeKind[] timeParameterTypes = { PrimitiveTypeKind.DateTimeOffset,
                                         PrimitiveTypeKind.DateTime, 
                                         PrimitiveTypeKind.Time,
                                       }; 
            foreach (string timeFunction in timeFunctions) 
            {
                foreach (PrimitiveTypeKind kind in timeParameterTypes) 
                {
                    functions.Add(CreateCannonicalFunction(timeFunction,
                                          CreateReturnParameter(PrimitiveTypeKind.Int32),
                                          CreateFirstParameter(kind))); 
                }
            } 
 

            EdmFunction dateFunction = CreateCannonicalFunction("CurrentDateTime", 
                                                                 CreateReturnParameter(PrimitiveTypeKind.DateTime));
            functions.Add(dateFunction);

            EdmFunction dateTimeOffsetFunction = CreateCannonicalFunction("CurrentDateTimeOffset", 
                                           CreateReturnParameter(PrimitiveTypeKind.DateTimeOffset));
            functions.Add(dateTimeOffsetFunction); 
 
            functions.Add(CreateCannonicalFunction("GetTotalOffsetMinutes",
                                                  CreateReturnParameter(PrimitiveTypeKind.Int32), 
                                                  CreateFirstParameter(PrimitiveTypeKind.DateTimeOffset)));

            dateFunction = CreateCannonicalFunction("CurrentUtcDateTime",
                               CreateReturnParameter(PrimitiveTypeKind.DateTime)); 
            functions.Add(dateFunction);
            #endregion // DateTime Functions 
            #region Math Functions 

            string[] mathFunctions = { "Round", "Floor", "Ceiling" }; 

            // Overloads for ROUND, FLOOR, CEILING functions
            PrimitiveTypeKind[] roundParameterTypes = { PrimitiveTypeKind.Single,
                                          PrimitiveTypeKind.Double, 
                                          PrimitiveTypeKind.Decimal };
 
            foreach (string functionName in mathFunctions) 
            {
                foreach (PrimitiveTypeKind kind in roundParameterTypes) 
                {
                    functions.Add(CreateCannonicalFunction(functionName,
                                                  CreateReturnParameter(kind),
                                                  CreateFirstParameter(kind))); 
                }
            } 
 
            // Overloads for ABS functions
            PrimitiveTypeKind[] absParameterTypes = { PrimitiveTypeKind.Decimal, 
                                        PrimitiveTypeKind.Double,
                                        PrimitiveTypeKind.Int16,
                                        PrimitiveTypeKind.Int32,
                                        PrimitiveTypeKind.Int64, 
                                        PrimitiveTypeKind.Byte,
                                        PrimitiveTypeKind.Single }; 
 
            foreach (PrimitiveTypeKind kind in absParameterTypes)
            { 
                functions.Add(CreateCannonicalFunction("Abs",
                                              CreateReturnParameter(kind),
                                              CreateFirstParameter(kind)));
            } 
            #endregion // Math Functions
 
            #region Bitwise Functions 

            string[] bitwiseFunctions = { "BitwiseAnd", "BitwiseOr", "BitwiseXor" }; 

            // Overloads for BitwiseAND, BitwiseNOT, BitwiseOR, BitwiseXOR functions
            PrimitiveTypeKind[] bitwiseFunctionOverloads = { PrimitiveTypeKind.Int16,
                                               PrimitiveTypeKind.Int32, 
                                               PrimitiveTypeKind.Int64,
                                               PrimitiveTypeKind.Byte }; 
 
            foreach (string functionName in bitwiseFunctions)
            { 
                foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
                {
                    functions.Add(CreateCannonicalFunction(functionName,
                                                  CreateReturnParameter(kind), 
                                                  CreateFirstParameter(kind),
                                                  CreateSecondParameter(kind))); 
                } 
            }
 
            foreach (PrimitiveTypeKind kind in bitwiseFunctionOverloads)
            {
                functions.Add(CreateCannonicalFunction("BitwiseNot",
                                              CreateReturnParameter(kind), 
                                              CreateFirstParameter(kind)));
            } 
            #endregion 

            #region Misc Functions 
            functions.Add(CreateCannonicalFunction("NewGuid",
                                          CreateReturnParameter(PrimitiveTypeKind.Guid)));
            #endregion // Misc Functions
 
            //Set all the functions to readonly
            foreach (EdmFunction function in functions) 
            { 
                function.SetReadOnly();
            } 

            System.Collections.ObjectModel.ReadOnlyCollection readOnlyFunctions = new System.Collections.ObjectModel.ReadOnlyCollection(functions);

            Interlocked.CompareExchange>(ref _functions, readOnlyFunctions, null); 
        }
 
        private static EdmFunction CreateAggregateCannonicalFunction(string name, FunctionParameter returnParameter, FunctionParameter parameter) 
        {
            Debug.Assert(name != null && returnParameter != null && parameter != null, "did you choose the wrong overload"); 

            EdmFunction function = new EdmFunction( name,
                EdmConstants.CanonicalFunctionNamespace,
                DataSpace.CSpace, 
                new EdmFunctionPayload
                { 
                    IsAggregate = true, 
                    IsBuiltIn = true,
                    ReturnParameter = returnParameter, 
                    Parameters = new FunctionParameter[1] { parameter },
                });
            return function;
 
        }
 
        private static EdmFunction CreateCannonicalFunction(string name, FunctionParameter returnParameter, params FunctionParameter []  parameters) 
        {
            Debug.Assert(name != null && returnParameter != null && parameters != null, "did you choose the wrong overload"); 

            EdmFunction function = new EdmFunction(name,
                EdmConstants.CanonicalFunctionNamespace,
                DataSpace.CSpace, 
                new EdmFunctionPayload
                { 
                    IsBuiltIn = true, 
                    ReturnParameter = returnParameter,
                    Parameters = parameters, 
                });
            return function;

        } 

        #region Edm Provider Specific Functionality 
        ///  
        /// Returns the list of super-types for the given primitiveType
        ///  
        /// 
        /// 
        internal System.Collections.ObjectModel.ReadOnlyCollection GetPromotionTypes(PrimitiveType primitiveType)
        { 
            InitializePromotableTypes();
 
            return _promotionTypes[(int)primitiveType.PrimitiveTypeKind]; 
        }
 
        /// 
        /// Initializes Promotion Type relation
        /// 
        private void InitializePromotableTypes() 
        {
            if (null != _promotionTypes) 
            { 
                return;
            } 

            System.Collections.ObjectModel.ReadOnlyCollection[] promotionTypes = new System.Collections.ObjectModel.ReadOnlyCollection[EdmConstants.NumPrimitiveTypes];

            for (int i = 0; i < EdmConstants.NumPrimitiveTypes; i++) 
            {
                promotionTypes[i] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { _primitiveTypes[i] }); 
            } 

            // 
            // PrimitiveTypeKind.Byte
            //
            promotionTypes[(int)PrimitiveTypeKind.Byte] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Byte], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int16],
                _primitiveTypes[(int)PrimitiveTypeKind.Int32], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int64], 
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single], 
                _primitiveTypes[(int)PrimitiveTypeKind.Double]
            });

            // 
            // PrimitiveTypeKind.Int16
            // 
            promotionTypes[(int)PrimitiveTypeKind.Int16] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { 
                _primitiveTypes[(int)PrimitiveTypeKind.Int16],
                _primitiveTypes[(int)PrimitiveTypeKind.Int32], 
                _primitiveTypes[(int)PrimitiveTypeKind.Int64],
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single],
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 
            // 
            // PrimitiveTypeKind.Int32
            // 
            promotionTypes[(int)PrimitiveTypeKind.Int32] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Int32],
                _primitiveTypes[(int)PrimitiveTypeKind.Int64],
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal], 
                _primitiveTypes[(int)PrimitiveTypeKind.Single],
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            }); 

            // 
            // PrimitiveTypeKind.Int64
            //
            promotionTypes[(int)PrimitiveTypeKind.Int64] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Int64], 
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal],
                _primitiveTypes[(int)PrimitiveTypeKind.Single], 
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 

            //
            // PrimitiveTypeKind.Decimal
            // 
            promotionTypes[(int)PrimitiveTypeKind.Decimal] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Decimal] 
            }); 

            // 
            // PrimitiveTypeKind.Single
            //
            promotionTypes[(int)PrimitiveTypeKind.Single] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Double] 
            });
 
            // 
            // PrimitiveTypeKind.DateTime
            // 
            promotionTypes[(int)PrimitiveTypeKind.DateTime] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.DateTime]
            });
 
            //
            // PrimitiveTypeKind.Time 
            // 
            promotionTypes[(int)PrimitiveTypeKind.Time] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] {
                _primitiveTypes[(int)PrimitiveTypeKind.Time] 
            });

            //
            // PrimitiveTypeKind.DateTimeOffset 
            //
            promotionTypes[(int)PrimitiveTypeKind.DateTimeOffset] = new System.Collections.ObjectModel.ReadOnlyCollection(new PrimitiveType[] { 
                _primitiveTypes[(int)PrimitiveTypeKind.DateTimeOffset] 
            });
 
            Interlocked.CompareExchange[]>(ref _promotionTypes,
                                                                             promotionTypes,
                                                                             null);
        } 

        internal TypeUsage GetCanonicalModelTypeUsage(PrimitiveTypeKind primitiveTypeKind) 
        { 
            if (null == _canonicalModelTypes)
            { 
                InitializeCanonicalModelTypes();
            }
            return _canonicalModelTypes[(int)primitiveTypeKind];
        } 

        ///  
        /// Initializes Canonical Model Types 
        /// 
        private void InitializeCanonicalModelTypes() 
        {
            TypeUsage[] canonicalTypes = new TypeUsage[EdmConstants.NumPrimitiveTypes];
            for (int primitiveTypeIndex = 0; primitiveTypeIndex < EdmConstants.NumPrimitiveTypes; primitiveTypeIndex++)
            { 
                PrimitiveType primitiveType = _primitiveTypes[primitiveTypeIndex];
                TypeUsage typeUsage = TypeUsage.CreateDefaultTypeUsage(primitiveType); 
                Debug.Assert(null != typeUsage, "TypeUsage must not be null"); 
                canonicalTypes[primitiveTypeIndex] = typeUsage;
            } 

            Interlocked.CompareExchange(ref _canonicalModelTypes, canonicalTypes, null);
        }
        #endregion 

        #region DbProviderManifest Interface 
        ///  
        /// Returns all the primitive types supported by the provider manifest
        ///  
        /// A collection of primitive types
        public override System.Collections.ObjectModel.ReadOnlyCollection GetStoreTypes()
        {
            InitializePrimitiveTypes(); 
            return _primitiveTypes;
        } 
 
        public override TypeUsage GetEdmType(TypeUsage storeType)
        { 
            throw new NotImplementedException();
        }

        public override TypeUsage GetStoreType(TypeUsage edmType) 
        {
            throw new NotImplementedException(); 
        } 

        internal TypeUsage ForgetScalarConstraints(TypeUsage type) 
        {
            PrimitiveType primitiveType = type.EdmType as PrimitiveType;
            Debug.Assert(primitiveType != null, "type argument must be primitive in order to use this function");
            if (primitiveType != null) 
            {
                return GetCanonicalModelTypeUsage(primitiveType.PrimitiveTypeKind); 
            } 
            else
            { 
                return type;
            }
        }
 
        /// 
        /// Providers should override this to return information specific to their provider. 
        /// 
        /// This method should never return null.
        ///  
        /// The name of the information to be retrieved.
        /// An XmlReader at the begining of the information requested.
        protected override System.Xml.XmlReader GetDbInformation(string informationType)
        { 
            throw new NotImplementedException();
        } 
        #endregion 

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK