public void GetAllPrimitiveTypes_returns_all_primitive_types_for_version() { foreach (var schemaVersion in EntityFrameworkVersion.GetAllVersions()) { // remove geo spatial types for schema versions V1 and V2 var expectedTypes = PrimitiveType .GetEdmPrimitiveTypes() .Where(t => schemaVersion == EntityFrameworkVersion.Version3 || !IsGeoSpatialType(t)) .Select(t => t.Name); Assert.Equal(expectedTypes, ModelHelper.AllPrimitiveTypes(schemaVersion)); } }
protected override void InvokeInternal(CommandProcessorContext cpc) { var artifact = cpc.EditingContext.GetEFArtifactService().Artifact; if (null == artifact) { Debug.Fail("null artifact not allowed"); return; } // safety check, this should never be hit Debug.Assert(_schemaProcedure != null, "InvokeInternal is called when _schemaProcedure is null"); if (null == _schemaProcedure) { throw new InvalidOperationException("InvokeInternal is called when _schemaProcedure is null."); } var cModel = artifact.ConceptualModel(); if (null == cModel) { Debug.Fail("ConceptualEntityModel not allowed"); return; } var cContainer = cModel.FirstEntityContainer as ConceptualEntityContainer; if (null == cContainer) { Debug.Fail("ConceptualEntityContainer not allowed"); return; } var sModel = artifact.StorageModel(); if (null == sModel) { Debug.Fail("null StorageEntityModel not allowed"); return; } // determine matching Function var funcObj = DatabaseObject.CreateFromSchemaProcedure(_schemaProcedure); var function = ModelHelper.FindFunction(sModel, funcObj); if (null == function) { // in some error scenarios where the model has not been properly created we can be asked to create a FunctionImport for a Function which does not exist // if so just return without creating return; } // do not produce FunctionImports for composable Functions unless _shouldCreateComposableFunctionImport is true if (false == _shouldCreateComposableFunctionImport && function.IsComposable.Value) { return; } // determine FunctionImport name and make sure it is unique var functionImportName = OverrideNameValue; if (String.IsNullOrWhiteSpace(functionImportName)) { if (null == function.LocalName || string.IsNullOrEmpty(function.LocalName.Value)) { Debug.Fail("null or empty LocalName attribute for matching Function " + function); return; } functionImportName = ModelHelper.GetUniqueName(typeof(FunctionImport), cContainer, function.LocalName.Value); } else { #if DEBUG string errorMessage; var isUnique = ModelHelper.IsUniqueName(typeof(FunctionImport), cContainer, functionImportName, false, out errorMessage); Debug.Assert(isUnique, "If we gave CreateMatchingFunctionImportCommand a name, it should have been unique"); #endif } object returnType = null; ComplexType existingComplexTypeReturnType = null; if (OverrideReturnTypeValue == null) { // get return type of the Function returnType = ConstructReturnType(_schemaProcedure, cModel, sModel, functionImportName); if (null == returnType) { Debug.Fail("cannot determine return type for schemaProcedure " + _schemaProcedure); return; } } else { if (OverrideReturnTypeValue.Equals(ModelConstants.NoneValue, StringComparison.Ordinal)) { returnType = Resources.NoneDisplayValueUsedForUX; } else { var rawValue = ModelHelper.UnwrapCollectionAroundFunctionImportReturnType(OverrideReturnTypeValue); // Here we attempt to find the corresponding ReturnType for the given ReturnTypeOverride. // The ReturnTypeOverride will be specified as the actual XAttribute value of the return type if (OverrideEntitySetValue != null) { if (ModelHelper.FindEntitySet(cpc.Artifact.ConceptualModel(), OverrideEntitySetValue) != null) { // ReturnType is an EntityType returnType = ModelHelper.FindEntityTypeViaSymbol(cpc.Artifact.ConceptualModel(), rawValue); } } else if (!ModelHelper.AllPrimitiveTypes(artifact.SchemaVersion).Contains(rawValue)) { // ReturnType is a ComplexType existingComplexTypeReturnType = ModelHelper.FindComplexType(cpc.Artifact.ConceptualModel(), rawValue); returnType = existingComplexTypeReturnType; } else { returnType = rawValue; } } } // Composable functions that do not return collections (e.g. scalar valued functions) are not supported // and should not be imported to the conceptual model if (Resources.NoneDisplayValueUsedForUX.Equals(returnType) && function.IsComposable.Value) { return; } // list of commands to be executed IList <Command> commands = new List <Command>(); // if return type is the name of a ComplexType then create a new matching ComplexType CreateComplexTypeCommand createComplexTypeCommand = null; if (OverrideReturnTypeValue == null && returnType is string && false == Resources.NoneDisplayValueUsedForUX.Equals(returnType)) { createComplexTypeCommand = AddCreateComplexTypeCommands(sModel, returnType as string, _schemaProcedure.RawColumns, commands); } // if we created a ComplexType above then pass that as a pre-req to the CreateFunctionImport command, // otherwise just create the FunctionImport without the pre-req CreateFunctionImportCommand cmdFuncImp; if (createComplexTypeCommand == null) { if (returnType is EdmType) { // For the case where the FunctionImport should have a return type which is not a Complex Type but // simply a C-side primitive type we have to pass the _name_ of the C-side primitive type to // CreateFunctionImportCommand, rather than the type itself returnType = (returnType as EdmType).Name; } cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, returnType); } else { cmdFuncImp = new CreateFunctionImportCommand(cContainer, function, functionImportName, createComplexTypeCommand); } commands.Add(cmdFuncImp); // now create the FunctionImportMapping to map the S-side Function to the C-side FunctionImport if (null != artifact.MappingModel() && null != artifact.MappingModel().FirstEntityContainerMapping) { var cmdFuncImpMapping = new CreateFunctionImportMappingCommand( artifact.MappingModel().FirstEntityContainerMapping, function, cmdFuncImp.Id); cmdFuncImpMapping.AddPreReqCommand(cmdFuncImp); commands.Add(cmdFuncImpMapping); IDictionary <string, string> mapPropertyNameToColumnName = null; if (_schemaProcedure != null) { mapPropertyNameToColumnName = ModelHelper.ConstructComplexTypePropertyNameToColumnNameMapping( _schemaProcedure.RawColumns.Select(c => c.Name).ToList()); } // Create explicit function-import result type mapping if the return type is a complex type. if (createComplexTypeCommand != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, createComplexTypeCommand) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } else if (OverrideReturnTypeValue != null && existingComplexTypeReturnType != null) { commands.Add( new CreateFunctionImportTypeMappingCommand(cmdFuncImpMapping, existingComplexTypeReturnType) { CreateDefaultScalarProperties = true, PropertyNameToColumnNameMap = mapPropertyNameToColumnName }); } } // now invoke the list of commands if (null != commands) { var cp = new CommandProcessor(cpc, commands); cp.Invoke(); // assign the generated FunctionImport so this command can be used as input for others _generatedFunctionImport = cmdFuncImp.FunctionImport; } }
protected override void InvokeInternal(CommandProcessorContext cpc) { // safety check, this should never be hit if (Container == null || (Function == null && ParameterDefinitions == null) || ReturnSingleType == null) { throw new InvalidOperationException( "InvokeInternal is called when Container or Function or ParameterDefinitions or ReturnSingleType is null"); } _fi = new FunctionImport(Container, null); _fi.LocalName.Value = FunctionImportName; // if we are using a high enough EDMX schema version then set IsComposable attribute if (EdmFeatureManager.GetComposableFunctionImportFeatureState(_fi.Artifact.SchemaVersion).IsEnabled()) { // if Function.IsComposable is true set _fi.IsComposable to true also, but if it's false then // leave _fi.IsComposable unset which is equivalent to false if (Function.IsComposable.Value) { _fi.IsComposable.Value = BoolOrNone.TrueValue; } } // if the return type is an EntityType, set the EntitySet attribute to // that EntityType's EntitySet. For other functions, don't set // the EntitySet. var returnSingleTypeString = ReturnSingleType as string; var returnSingleTypeComplexType = ReturnSingleType as ComplexType; var returnSingleTypeEntity = ReturnSingleType as EntityType; Debug.Assert( returnSingleTypeString != null || returnSingleTypeComplexType != null || returnSingleTypeEntity != null, "Return Type for function import must be of type string or ComplexType or EntityType"); if (returnSingleTypeString != null) { // make sure that this is a primitive type or a complex type and build a "Collection()" around it. if (returnSingleTypeString != Tools.XmlDesignerBase.Resources.NoneDisplayValueUsedForUX) { var edmPrimitiveTypes = ModelHelper.AllPrimitiveTypes(_fi.Artifact.SchemaVersion); if (!edmPrimitiveTypes.Contains(returnSingleTypeString)) { var msg = string.Format(CultureInfo.CurrentCulture, Resources.INVALID_FORMAT, returnSingleTypeString); throw new CommandValidationFailedException(msg); } _fi.ReturnTypeAsPrimitiveType.Value = String.Format( CultureInfo.InvariantCulture, FunctionImport.CollectionFormat, returnSingleTypeString); } } else if (returnSingleTypeComplexType != null) { var complexTypes = _fi.Artifact.ConceptualModel().ComplexTypes(); if (!complexTypes.Contains(returnSingleTypeComplexType)) { var msg = string.Format( CultureInfo.CurrentCulture, Resources.INVALID_FORMAT, returnSingleTypeComplexType.NormalizedNameExternal); throw new CommandValidationFailedException(msg); } _fi.ReturnTypeAsComplexType.SetRefName(returnSingleTypeComplexType); } else if (returnSingleTypeEntity != null) { _fi.EntitySet.SetRefName(returnSingleTypeEntity.EntitySet); _fi.ReturnTypeAsEntityType.SetRefName(returnSingleTypeEntity); } Container.AddFunctionImport(_fi); XmlModelHelper.NormalizeAndResolve(_fi); if (ParameterDefinitions != null) { UpdateFunctionImportParameters(cpc, _fi, ParameterDefinitions); } if (Function != null) { UpdateFunctionImportParameters(cpc, _fi, Function); } }