Пример #1
0
        private static void BuildSPRenamediagram(DbModel model, ReadOnlyCollection <PrimitiveType> storeTypes)
        {
            EdmFunctionPayload payload = new EdmFunctionPayload {
                Schema = "dbo", StoreFunctionName = "sp_renamediagram", IsComposable = false
            };

            payload.Parameters = new List <FunctionParameter>();
            payload.Parameters.Add(FunctionParameter.Create("diagramname", GetEdmType(model, storeTypes, PrimitiveTypeKind.String), ParameterMode.In));
            payload.Parameters.Add(FunctionParameter.Create("owner_id", GetEdmType(model, storeTypes, PrimitiveTypeKind.Int32), ParameterMode.In));
            payload.Parameters.Add(FunctionParameter.Create("new_diagramname", GetEdmType(model, storeTypes, PrimitiveTypeKind.String), ParameterMode.In));
            EdmFunction function = EdmFunction.Create("sp_renamediagram", "CodeFirstDatabaseSchema", DataSpace.SSpace, payload, null);

            model.StoreModel.AddItem(function);

            EdmFunctionPayload payloadImport = new EdmFunctionPayload {
                IsFunctionImport = true, IsComposable = false
            };

            payloadImport.Parameters = new List <FunctionParameter>();
            payloadImport.Parameters.Add(FunctionParameter.Create("diagramname", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In));
            payloadImport.Parameters.Add(FunctionParameter.Create("owner_id", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.In));
            payloadImport.Parameters.Add(FunctionParameter.Create("new_diagramname", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String), ParameterMode.In));
            EdmFunction functionImport = EdmFunction.Create("sp_renamediagram", "CodeFirstNamespace", DataSpace.CSpace, payloadImport, null);

            model.ConceptualModel.Container.AddFunctionImport(functionImport);

            FunctionImportResultMapping        functionImportResultMapping = null;
            FunctionImportMappingNonComposable functionImportMapping       = CreateFunctionImportMappingNonComposable(functionImport, function, functionImportResultMapping, model.ConceptualToStoreMapping);

            model.ConceptualToStoreMapping.AddFunctionImportMapping(functionImportMapping);
        }
        /// <summary>
        /// Determines the store type for a function import.
        /// </summary>
        private TypeUsage DetermineStoreResultType(MetadataWorkspace workspace, FunctionImportMappingNonComposable mapping, int resultSetIndex, out IColumnMapGenerator columnMapGenerator)
        {
            // Determine column maps and infer result types for the mapped function. There are four varieties:
            // Collection(Entity)
            // Collection(PrimitiveType)
            // Collection(ComplexType)
            // No result type
            TypeUsage storeResultType;

            {
                StructuralType baseStructuralType;
                EdmFunction    functionImport = mapping.FunctionImport;

                // Collection(Entity) or Collection(ComplexType)
                if (MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(functionImport, resultSetIndex, out baseStructuralType))
                {
                    ValidateEdmResultType(baseStructuralType, functionImport);

                    //Note: Defensive check for historic reasons, we expect functionImport.EntitySets.Count > resultSetIndex
                    EntitySet entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : null;

                    columnMapGenerator = new FunctionColumnMapGenerator(mapping, resultSetIndex, entitySet, baseStructuralType);

                    // We don't actually know the return type for the stored procedure, but we can infer
                    // one based on the mapping (i.e.: a column for every property of the mapped types
                    // and for all discriminator columns)
                    storeResultType = mapping.GetExpectedTargetResultType(workspace, resultSetIndex);
                }

                // Collection(PrimitiveType)
                else
                {
                    FunctionParameter returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex);
                    if (returnParameter != null && returnParameter.TypeUsage != null)
                    {
                        // Get metadata description of the return type
                        storeResultType = returnParameter.TypeUsage;
                        Debug.Assert(storeResultType.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType, "FunctionImport currently supports only collection result type");
                        TypeUsage elementType = ((CollectionType)storeResultType.EdmType).TypeUsage;
                        Debug.Assert(Helper.IsScalarType(elementType.EdmType)
                                     , "FunctionImport supports only Collection(Entity), Collection(Enum) and Collection(Primitive)");

                        // Build collection column map where the first column of the store result is assumed
                        // to contain the primitive type values.
                        ScalarColumnMap           scalarColumnMap     = new ScalarColumnMap(elementType, string.Empty, 0, 0);
                        SimpleCollectionColumnMap collectionColumnMap = new SimpleCollectionColumnMap(storeResultType,
                                                                                                      string.Empty, scalarColumnMap, null, null);
                        columnMapGenerator = new ConstantColumnMapGenerator(collectionColumnMap, 1);
                    }

                    // No result type
                    else
                    {
                        storeResultType    = null;
                        columnMapGenerator = new ConstantColumnMapGenerator(null, 0);
                    }
                }
            }
            return(storeResultType);
        }
 internal FunctionColumnMapGenerator(FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType)
 {
     _mapping            = mapping;
     _entitySet          = entitySet;
     _baseStructuralType = baseStructuralType;
     _resultSetIndex     = resultSetIndex;
 }
        private TypeUsage DetermineStoreResultType(
            FunctionImportMappingNonComposable mapping,
            int resultSetIndex,
            out EntityCommandDefinition.IColumnMapGenerator columnMapGenerator)
        {
            EdmFunction    functionImport = mapping.FunctionImport;
            StructuralType returnType;
            TypeUsage      type;

            if (MetadataHelper.TryGetFunctionImportReturnType <StructuralType>(functionImport, resultSetIndex, out returnType))
            {
                EntityCommandDefinition.ValidateEdmResultType((EdmType)returnType, functionImport);
                EntitySet entitySet = functionImport.EntitySets.Count > resultSetIndex ? functionImport.EntitySets[resultSetIndex] : (EntitySet)null;
                columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.FunctionColumnMapGenerator(mapping, resultSetIndex, entitySet, returnType, this._columnMapFactory);
                type = mapping.GetExpectedTargetResultType(resultSetIndex);
            }
            else
            {
                FunctionParameter returnParameter = MetadataHelper.GetReturnParameter(functionImport, resultSetIndex);
                if (returnParameter != null && returnParameter.TypeUsage != null)
                {
                    type = returnParameter.TypeUsage;
                    ScalarColumnMap           scalarColumnMap     = new ScalarColumnMap(((CollectionType)type.EdmType).TypeUsage, string.Empty, 0, 0);
                    SimpleCollectionColumnMap collectionColumnMap = new SimpleCollectionColumnMap(type, string.Empty, (ColumnMap)scalarColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null);
                    columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator((ColumnMap)collectionColumnMap, 1);
                }
                else
                {
                    type = (TypeUsage)null;
                    columnMapGenerator = (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator((ColumnMap)null, 0);
                }
            }
            return(type);
        }
Пример #5
0
        // <summary>
        // Creates a column map for the given reader and function mapping.
        // </summary>
        internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap(
            DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet,
            StructuralType baseStructuralType)
        {
            var resultMapping = mapping.GetResultMapping(resultSetIndex);

            Debug.Assert(resultMapping != null);
            if (resultMapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader
            {
                // if there is no mapping, create default mapping to root entity type or complex type
                Debug.Assert(!baseStructuralType.Abstract, "mapping loader must verify abstract types have explicit mapping");

                return(CreateColumnMapFromReaderAndType(
                           storeDataReader, baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping));
            }

            // the section below deals with the polymorphic entity type mapping for return type
            var baseEntityType = baseStructuralType as EntityType;

            Debug.Assert(null != baseEntityType, "We should have entity type here");

            // Generate column maps for all discriminators
            var discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex);

            // Generate default maps for all mapped entity types
            var mappedEntityTypes = new HashSet <EntityType>(resultMapping.MappedEntityTypes);

            mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented
            var typeChoices = new Dictionary <EntityType, TypedColumnMap>(mappedEntityTypes.Count);

            ColumnMap[] baseTypeColumnMaps = null;
            foreach (var entityType in mappedEntityTypes)
            {
                var propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType, resultMapping.ReturnTypeColumnsRenameMapping);
                var entityColumnMap    = CreateEntityTypeElementColumnMap(
                    storeDataReader, entityType, entitySet, propertyColumnMaps, resultMapping.ReturnTypeColumnsRenameMapping);
                if (!entityType.Abstract)
                {
                    typeChoices.Add(entityType, entityColumnMap);
                }
                if (entityType == baseStructuralType)
                {
                    baseTypeColumnMaps = propertyColumnMaps;
                }
            }

            // NOTE: We don't have a null sentinel here, because the stored proc won't
            //       return one anyway; we'll just presume the data's always there.
            var polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap(
                TypeUsage.Create(baseStructuralType), baseStructuralType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices,
                (object[] discriminatorValues) => mapping.Discriminate(discriminatorValues, resultSetIndex));
            CollectionColumnMap collection = new SimpleCollectionColumnMap(
                baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, polymorphicMap, null, null);

            return(collection);
        }
 public void WriteFunctionImportMappingElement(
     FunctionImportMappingNonComposable functionImportMapping)
 {
     this.WriteFunctionImportMappingStartElement((FunctionImportMapping)functionImportMapping);
     foreach (FunctionImportResultMapping resultMapping in functionImportMapping.ResultMappings)
     {
         this.WriteFunctionImportResultMappingElement(resultMapping);
     }
     this.WriteFunctionImportEndElement();
 }
Пример #7
0
        public void WriteFunctionImportMappingElement(FunctionImportMappingNonComposable functionImportMapping)
        {
            DebugCheck.NotNull(functionImportMapping);

            WriteFunctionImportMappingStartElement(functionImportMapping);

            foreach (var resultMapping in functionImportMapping.ResultMappings)
            {
                WriteFunctionImportResultMappingElement(resultMapping);
            }

            WriteFunctionImportEndElement();
        }
 internal FunctionColumnMapGenerator(
     FunctionImportMappingNonComposable mapping,
     int resultSetIndex,
     EntitySet entitySet,
     StructuralType baseStructuralType,
     ColumnMapFactory columnMapFactory)
 {
     this._mapping            = mapping;
     this._entitySet          = entitySet;
     this._baseStructuralType = baseStructuralType;
     this._resultSetIndex     = resultSetIndex;
     this._columnMapFactory   = columnMapFactory;
 }
        private static ScalarColumnMap[] CreateDiscriminatorColumnMaps(
            DbDataReader storeDataReader,
            FunctionImportMappingNonComposable mapping,
            int resultIndex)
        {
            TypeUsage      type = TypeUsage.Create((EdmType)MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String));
            IList <string> discriminatorColumns = mapping.GetDiscriminatorColumns(resultIndex);

            ScalarColumnMap[] scalarColumnMapArray = new ScalarColumnMap[discriminatorColumns.Count];
            for (int index = 0; index < scalarColumnMapArray.Length; ++index)
            {
                string          str             = discriminatorColumns[index];
                ScalarColumnMap scalarColumnMap = new ScalarColumnMap(type, str, 0, ColumnMapFactory.GetDiscriminatorOrdinalFromReader(storeDataReader, str, mapping.FunctionImport));
                scalarColumnMapArray[index] = scalarColumnMap;
            }
            return(scalarColumnMapArray);
        }
Пример #10
0
        private static void BuildSPUpgraddiagram(DbModel model, ReadOnlyCollection <PrimitiveType> storeTypes)
        {
            EdmFunctionPayload payload = new EdmFunctionPayload {
                Schema = "dbo", StoreFunctionName = "sp_upgraddiagrams", IsComposable = false
            };
            EdmFunction function = EdmFunction.Create("sp_upgraddiagrams", "CodeFirstDatabaseSchema", DataSpace.SSpace, payload, null);

            model.StoreModel.AddItem(function);

            EdmFunctionPayload payloadImport = new EdmFunctionPayload {
                IsFunctionImport = true, IsComposable = false
            };
            EdmFunction functionImport = EdmFunction.Create("sp_upgraddiagrams", "CodeFirstNamespace", DataSpace.CSpace, payloadImport, null);

            model.ConceptualModel.Container.AddFunctionImport(functionImport);

            FunctionImportResultMapping        functionImportResultMapping = null;
            FunctionImportMappingNonComposable functionImportMapping       = CreateFunctionImportMappingNonComposable(functionImport, function, functionImportResultMapping, model.ConceptualToStoreMapping);

            model.ConceptualToStoreMapping.AddFunctionImportMapping(functionImportMapping);
        }
        internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap(
            DbDataReader storeDataReader,
            FunctionImportMappingNonComposable mapping,
            int resultSetIndex,
            EntitySet entitySet,
            StructuralType baseStructuralType)
        {
            FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex);

            if (resultMapping.NormalizedEntityTypeMappings.Count == 0)
            {
                return(this.CreateColumnMapFromReaderAndType(storeDataReader, (EdmType)baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping));
            }
            EntityType entityType = baseStructuralType as EntityType;

            ScalarColumnMap[]    discriminatorColumnMaps = ColumnMapFactory.CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex);
            HashSet <EntityType> entityTypeSet           = new HashSet <EntityType>((IEnumerable <EntityType>)resultMapping.MappedEntityTypes);

            entityTypeSet.Add(entityType);
            Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(entityTypeSet.Count);

            ColumnMap[] baseTypeColumns = (ColumnMap[])null;
            foreach (EntityType key in entityTypeSet)
            {
                ColumnMap[]     columnMapsForType = ColumnMapFactory.GetColumnMapsForType(storeDataReader, (EdmType)key, resultMapping.ReturnTypeColumnsRenameMapping);
                EntityColumnMap elementColumnMap  = ColumnMapFactory.CreateEntityTypeElementColumnMap(storeDataReader, (EdmType)key, entitySet, columnMapsForType, resultMapping.ReturnTypeColumnsRenameMapping);
                if (!key.Abstract)
                {
                    typeChoices.Add(key, (TypedColumnMap)elementColumnMap);
                }
                if (key == baseStructuralType)
                {
                    baseTypeColumns = columnMapsForType;
                }
            }
            MultipleDiscriminatorPolymorphicColumnMap polymorphicColumnMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create((EdmType)baseStructuralType), baseStructuralType.Name, baseTypeColumns, (SimpleColumnMap[])discriminatorColumnMaps, typeChoices, (Func <object[], EntityType>)(discriminatorValues => mapping.Discriminate(discriminatorValues, resultSetIndex)));

            return((CollectionColumnMap) new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, (ColumnMap)polymorphicColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null));
        }
Пример #12
0
        private static ScalarColumnMap[] CreateDiscriminatorColumnMaps(
            DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultIndex)
        {
            // choose an arbitrary type for discriminator columns -- the type is not
            // actually statically known
            EdmType discriminatorType =
                MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String);
            var discriminatorTypeUsage =
                TypeUsage.Create(discriminatorType);

            var discriminatorColumnNames = mapping.GetDiscriminatorColumns(resultIndex);
            var discriminatorColumns     = new ScalarColumnMap[discriminatorColumnNames.Count];

            for (var i = 0; i < discriminatorColumns.Length; i++)
            {
                var columnName = discriminatorColumnNames[i];
                var columnMap  = new ScalarColumnMap(
                    discriminatorTypeUsage, columnName, 0,
                    GetDiscriminatorOrdinalFromReader(storeDataReader, columnName, mapping.FunctionImport));
                discriminatorColumns[i] = columnMap;
            }
            return(discriminatorColumns);
        }
Пример #13
0
        public void WriteFunctionImportMappingElement_writes_result_mapping_for_non_composable_functions_mapped_explicitly_to_EntityType()
        {
            var typeUsage =
                TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            var entityTypeProperty1 = new EdmProperty("ETProperty1", typeUsage);
            var entityTypeProperty2 = new EdmProperty("ETProperty2", typeUsage);

            var entityType = new EntityType("ET", "Ns", DataSpace.CSpace);

            entityType.AddMember(entityTypeProperty1);
            entityType.AddMember(entityTypeProperty2);

            var functionImport =
                new EdmFunction(
                    "f_c", "Ns", DataSpace.CSpace,
                    new EdmFunctionPayload
            {
                IsComposable     = false,
                IsFunctionImport = true,
                ReturnParameters =
                    new[]
                {
                    new FunctionParameter(
                        "ReturnValue",
                        TypeUsage.CreateDefaultTypeUsage(entityType.GetCollectionType()),
                        ParameterMode.ReturnValue)
                },
            });

            typeUsage = ProviderRegistry.Sql2008_ProviderManifest.GetStoreType(typeUsage);
            var rowTypeProperty1 = new EdmProperty("RTProperty1", typeUsage);
            var rowTypeProperty2 = new EdmProperty("RTProperty2", typeUsage);
            var rowType          = new RowType(new[] { rowTypeProperty1, rowTypeProperty2 });

            var storeFunction =
                new EdmFunction(
                    "f_s", "Ns.Store", DataSpace.SSpace,
                    new EdmFunctionPayload
            {
                IsComposable     = false,
                ReturnParameters =
                    new[]
                {
                    new FunctionParameter(
                        "Return",
                        TypeUsage.CreateDefaultTypeUsage(rowType),
                        ParameterMode.ReturnValue)
                },
            });

            var functionImportResultMapping = new FunctionImportResultMapping();

            functionImportResultMapping.AddTypeMapping(
                new FunctionImportEntityTypeMapping(
                    new EntityType[0],
                    new [] { entityType },
                    new Collections.ObjectModel.Collection <FunctionImportReturnTypePropertyMapping>()
            {
                new FunctionImportReturnTypeScalarPropertyMapping("ETProperty1", "RTProperty1"),
                new FunctionImportReturnTypeScalarPropertyMapping("ETProperty2", "RTProperty2")
            },
                    new FunctionImportEntityTypeMappingCondition[]
            {
                new FunctionImportEntityTypeMappingConditionIsNull("RTProperty1", false),
                new FunctionImportEntityTypeMappingConditionValue("RTProperty2", 4),
                new FunctionImportEntityTypeMappingConditionValue("FakeCondition", true)
            }
                    ));

            var mappingItemCollection =
                new StorageMappingItemCollection(
                    new EdmItemCollection(EdmModel.CreateConceptualModel()),
                    new StoreItemCollection(
                        EdmModel.CreateStoreModel(ProviderRegistry.Sql2008_ProviderInfo, ProviderRegistry.Sql2008_ProviderManifest)),
                    new string[0]);

            var containerMapping =
                new EntityContainerMapping(
                    new EntityContainer("C", DataSpace.CSpace), new EntityContainer("S", DataSpace.SSpace), mappingItemCollection, false);

            var functionImportMapping =
                new FunctionImportMappingNonComposable(
                    functionImport,
                    storeFunction,
                    new []
            {
                functionImportResultMapping
            },
                    containerMapping);

            containerMapping.AddFunctionImportMapping(functionImportMapping);

            var fixture = new Fixture();

            fixture.Writer.WriteFunctionImportMappingElement(functionImportMapping);
            Assert.Equal(
                @"<FunctionImportMapping FunctionName=""Ns.Store.f_s"" FunctionImportName=""f_c"">
  <ResultMapping>
    <EntityTypeMapping TypeName=""Ns.ET"">
      <ScalarProperty Name=""ETProperty1"" ColumnName=""RTProperty1"" />
      <ScalarProperty Name=""ETProperty2"" ColumnName=""RTProperty2"" />
      <Condition ColumnName=""RTProperty1"" IsNull=""false"" />
      <Condition ColumnName=""RTProperty2"" Value=""4"" />
      <Condition ColumnName=""FakeCondition"" Value=""1"" />
    </EntityTypeMapping>
  </ResultMapping>
</FunctionImportMapping>",
                fixture.ToString());
        }
Пример #14
0
        public void WriteFunctionImportMappingElement_does_not_write_result_mapping_for_non_composable_functions_mapped_implicitly()
        {
            var typeUsage =
                TypeUsage.CreateDefaultTypeUsage(PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32));

            var complexTypeProperty1 = new EdmProperty("CTProperty1", typeUsage);
            var complexTypeProperty2 = new EdmProperty("CTProperty2", typeUsage);

            var complexType = new ComplexType("CT", "Ns", DataSpace.CSpace);

            complexType.AddMember(complexTypeProperty1);
            complexType.AddMember(complexTypeProperty2);

            var functionImport =
                new EdmFunction(
                    "f_c", "Ns", DataSpace.CSpace,
                    new EdmFunctionPayload
            {
                IsComposable     = false,
                IsFunctionImport = true,
                ReturnParameters =
                    new[]
                {
                    new FunctionParameter(
                        "ReturnValue",
                        TypeUsage.CreateDefaultTypeUsage(complexType.GetCollectionType()),
                        ParameterMode.ReturnValue)
                },
            });

            typeUsage = ProviderRegistry.Sql2008_ProviderManifest.GetStoreType(typeUsage);
            var rowTypeProperty1 = new EdmProperty("RTProperty1", typeUsage);
            var rowTypeProperty2 = new EdmProperty("RTProperty2", typeUsage);
            var rowType          = new RowType(new[] { rowTypeProperty1, rowTypeProperty2 });

            var storeFunction =
                new EdmFunction(
                    "f_s", "Ns.Store", DataSpace.SSpace,
                    new EdmFunctionPayload
            {
                IsComposable     = false,
                ReturnParameters =
                    new[]
                {
                    new FunctionParameter(
                        "Return",
                        TypeUsage.CreateDefaultTypeUsage(rowType),
                        ParameterMode.ReturnValue)
                },
            });

            var functionImportMapping =
                new FunctionImportMappingNonComposable(
                    functionImport,
                    storeFunction,
                    new FunctionImportResultMapping[0],
                    new EntityContainerMapping(new EntityContainer("C", DataSpace.SSpace)));

            var fixture = new Fixture();

            fixture.Writer.WriteFunctionImportMappingElement(functionImportMapping);
            Assert.Equal(
                @"<FunctionImportMapping FunctionName=""Ns.Store.f_s"" FunctionImportName=""f_c"" />",
                fixture.ToString());
        }
        /// <summary>
        /// don't let this be constructed publicly;
        /// </summary>
        /// <exception cref="EntityCommandCompilationException">Cannot prepare the command definition for execution; consult the InnerException for more information.</exception>
        /// <exception cref="NotSupportedException">The ADO.NET Data Provider you are using does not support CommandTrees.</exception>
        internal EntityCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree)
        {
            EntityUtil.CheckArgumentNull(storeProviderFactory, "storeProviderFactory");
            EntityUtil.CheckArgumentNull(commandTree, "commandTree");

            DbProviderServices storeProviderServices = DbProviderServices.GetProviderServices(storeProviderFactory);

            try {
                if (DbCommandTreeKind.Query == commandTree.CommandTreeKind)
                {
                    // Next compile the plan for the command tree
                    List <ProviderCommandInfo> mappedCommandList = new List <ProviderCommandInfo>();
                    ColumnMap columnMap;
                    int       columnCount;
                    PlanCompiler.Compile(commandTree, out mappedCommandList, out columnMap, out columnCount, out _entitySets);
                    _columnMapGenerators = new IColumnMapGenerator[] { new ConstantColumnMapGenerator(columnMap, columnCount) };
                    // Note: we presume that the first item in the ProviderCommandInfo is the root node;
                    Debug.Assert(mappedCommandList.Count > 0, "empty providerCommandInfo collection and no exception?"); // this shouldn't ever happen.

                    // Then, generate the store commands from the resulting command tree(s)
                    _mappedCommandDefinitions = new List <DbCommandDefinition>(mappedCommandList.Count);

                    foreach (ProviderCommandInfo providerCommandInfo in mappedCommandList)
                    {
                        DbCommandDefinition providerCommandDefinition = storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree);

                        if (null == providerCommandDefinition)
                        {
                            throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.ProviderReturnedNullForCreateCommandDefinition);
                        }
                        _mappedCommandDefinitions.Add(providerCommandDefinition);
                    }
                }
                else
                {
                    Debug.Assert(DbCommandTreeKind.Function == commandTree.CommandTreeKind, "only query and function command trees are supported");
                    DbFunctionCommandTree entityCommandTree = (DbFunctionCommandTree)commandTree;

                    // Retrieve mapping and metadata information for the function import.
                    FunctionImportMappingNonComposable mapping          = GetTargetFunctionMapping(entityCommandTree);
                    IList <FunctionParameter>          returnParameters = entityCommandTree.EdmFunction.ReturnParameters;
                    int resultSetCount = returnParameters.Count > 1 ? returnParameters.Count : 1;
                    _columnMapGenerators = new IColumnMapGenerator[resultSetCount];
                    TypeUsage storeResultType = DetermineStoreResultType(entityCommandTree.MetadataWorkspace, mapping, 0, out _columnMapGenerators[0]);
                    for (int i = 1; i < resultSetCount; i++)
                    {
                        DetermineStoreResultType(entityCommandTree.MetadataWorkspace, mapping, i, out _columnMapGenerators[i]);
                    }
                    // Copy over parameters (this happens through a more indirect route in the plan compiler, but
                    // it happens nonetheless)
                    List <KeyValuePair <string, TypeUsage> > providerParameters = new List <KeyValuePair <string, TypeUsage> >();
                    foreach (KeyValuePair <string, TypeUsage> parameter in entityCommandTree.Parameters)
                    {
                        providerParameters.Add(parameter);
                    }

                    // Construct store command tree usage.
                    DbFunctionCommandTree providerCommandTree = new DbFunctionCommandTree(entityCommandTree.MetadataWorkspace, DataSpace.SSpace,
                                                                                          mapping.TargetFunction, storeResultType, providerParameters);

                    DbCommandDefinition storeCommandDefinition = storeProviderServices.CreateCommandDefinition(providerCommandTree);
                    _mappedCommandDefinitions = new List <DbCommandDefinition>(1)
                    {
                        storeCommandDefinition
                    };

                    EntitySet firstResultEntitySet = mapping.FunctionImport.EntitySets.FirstOrDefault();
                    if (firstResultEntitySet != null)
                    {
                        _entitySets = new Set <EntitySet>();
                        _entitySets.Add(mapping.FunctionImport.EntitySets.FirstOrDefault());
                        _entitySets.MakeReadOnly();
                    }
                }

                // Finally, build a list of the parameters that the resulting command should have;
                List <EntityParameter> parameterList = new List <EntityParameter>();

                foreach (KeyValuePair <string, TypeUsage> queryParameter in commandTree.Parameters)
                {
                    EntityParameter parameter = CreateEntityParameterFromQueryParameter(queryParameter);
                    parameterList.Add(parameter);
                }

                _parameters = new System.Collections.ObjectModel.ReadOnlyCollection <EntityParameter>(parameterList);
            }
            catch (EntityCommandCompilationException) {
                // No need to re-wrap EntityCommandCompilationException
                throw;
            }
            catch (Exception e) {
                // we should not be wrapping all exceptions
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    // we don't wan't folks to have to know all the various types of exceptions that can
                    // occur, so we just rethrow a CommandDefinitionException and make whatever we caught
                    // the inner exception of it.
                    throw EntityUtil.CommandCompilation(System.Data.Entity.Strings.EntityClient_CommandDefinitionPreparationFailed, e);
                }
                throw;
            }
        }
 internal EntityCommandDefinition(
     DbProviderFactory storeProviderFactory,
     DbCommandTree commandTree,
     DbInterceptionContext interceptionContext,
     IDbDependencyResolver resolver = null,
     BridgeDataReaderFactory bridgeDataReaderFactory = null,
     ColumnMapFactory columnMapFactory = null)
 {
     this._bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory((Translator)null);
     this._columnMapFactory        = columnMapFactory ?? new ColumnMapFactory();
     this._storeProviderServices   = (resolver != null ? resolver.GetService <DbProviderServices>((object)storeProviderFactory.GetProviderInvariantName()) : (DbProviderServices)null) ?? storeProviderFactory.GetProviderServices();
     try
     {
         if (commandTree.CommandTreeKind == DbCommandTreeKind.Query)
         {
             List <ProviderCommandInfo> providerCommands = new List <ProviderCommandInfo>();
             ColumnMap resultColumnMap;
             int       columnCount;
             System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Compile(commandTree, out providerCommands, out resultColumnMap, out columnCount, out this._entitySets);
             this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[1]
             {
                 (EntityCommandDefinition.IColumnMapGenerator) new EntityCommandDefinition.ConstantColumnMapGenerator(resultColumnMap, columnCount)
             };
             this._mappedCommandDefinitions = new List <DbCommandDefinition>(providerCommands.Count);
             foreach (ProviderCommandInfo providerCommandInfo in providerCommands)
             {
                 DbCommandDefinition commandDefinition = this._storeProviderServices.CreateCommandDefinition(providerCommandInfo.CommandTree, interceptionContext);
                 if (commandDefinition == null)
                 {
                     throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition);
                 }
                 this._mappedCommandDefinitions.Add(commandDefinition);
             }
         }
         else
         {
             DbFunctionCommandTree functionCommandTree = (DbFunctionCommandTree)commandTree;
             FunctionImportMappingNonComposable targetFunctionMapping = EntityCommandDefinition.GetTargetFunctionMapping(functionCommandTree);
             IList <FunctionParameter>          returnParameters      = (IList <FunctionParameter>)functionCommandTree.EdmFunction.ReturnParameters;
             int length = returnParameters.Count > 1 ? returnParameters.Count : 1;
             this._columnMapGenerators = new EntityCommandDefinition.IColumnMapGenerator[length];
             TypeUsage storeResultType = this.DetermineStoreResultType(targetFunctionMapping, 0, out this._columnMapGenerators[0]);
             for (int resultSetIndex = 1; resultSetIndex < length; ++resultSetIndex)
             {
                 this.DetermineStoreResultType(targetFunctionMapping, resultSetIndex, out this._columnMapGenerators[resultSetIndex]);
             }
             List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >();
             foreach (KeyValuePair <string, TypeUsage> parameter in functionCommandTree.Parameters)
             {
                 keyValuePairList.Add(parameter);
             }
             this._mappedCommandDefinitions = new List <DbCommandDefinition>(1)
             {
                 this._storeProviderServices.CreateCommandDefinition((DbCommandTree) new DbFunctionCommandTree(functionCommandTree.MetadataWorkspace, DataSpace.SSpace, targetFunctionMapping.TargetFunction, storeResultType, (IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList))
             };
             if (targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>() != null)
             {
                 this._entitySets = new Set <EntitySet>();
                 this._entitySets.Add(targetFunctionMapping.FunctionImport.EntitySets.FirstOrDefault <EntitySet>());
                 this._entitySets.MakeReadOnly();
             }
         }
         List <EntityParameter> entityParameterList = new List <EntityParameter>();
         foreach (KeyValuePair <string, TypeUsage> parameter in commandTree.Parameters)
         {
             EntityParameter fromQueryParameter = EntityCommandDefinition.CreateEntityParameterFromQueryParameter(parameter);
             entityParameterList.Add(fromQueryParameter);
         }
         this._parameters = new ReadOnlyCollection <EntityParameter>((IList <EntityParameter>)entityParameterList);
     }
     catch (EntityCommandCompilationException ex)
     {
         throw;
     }
     catch (Exception ex)
     {
         if (ex.IsCatchableExceptionType())
         {
             throw new EntityCommandCompilationException(Strings.EntityClient_CommandDefinitionPreparationFailed, ex);
         }
         throw;
     }
 }