// TODO perhaps build an in-memory "inference" model that keeps track of the assumptions we make (association/entity type names, etc.) /// <summary> /// Generates mapping specification language (MSL) based on the provided conceptual schema definition language (CSDL). /// </summary> /// <typeparam name="T"> The type of the activity output. </typeparam> /// <param name="owningActivity"> The currently executing activity. </param> /// <param name="context"> The activity context that contains the state of the workflow. </param> /// <param name="inputs"> Contains the incoming CSDL. </param> /// <returns> Mapping specification language (MSL) of type T based on the provided conceptual schema definition language (CSDL). </returns> public T GenerateActivityOutput <T>( OutputGeneratorActivity owningActivity, NativeActivityContext context, IDictionary <string, object> inputs) where T : class { _activity = owningActivity; object o; inputs.TryGetValue(EdmConstants.csdlInputName, out o); var edmItemCollection = o as EdmItemCollection; if (edmItemCollection == null) { throw new InvalidOperationException(Resources.ErrorCouldNotFindCSDL); } var symbolResolver = context.GetExtension <SymbolResolver>(); var edmParameterBag = symbolResolver[typeof(EdmParameterBag).Name] as EdmParameterBag; if (edmParameterBag == null) { throw new InvalidOperationException(Resources.ErrorNoEdmParameterBag); } // Find the TargetVersion parameter var targetFrameworkVersion = edmParameterBag.GetParameter <Version>(EdmParameterBag.ParameterName.TargetVersion); if (targetFrameworkVersion == null) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorNoParameterDefined, EdmParameterBag.ParameterName.TargetVersion)); } // Find the MSL namespace parameter _mslUri = SchemaManager.GetMSLNamespaceName(targetFrameworkVersion); _msl = _mslUri; var csdlNamespace = edmItemCollection.GetNamespace(); var mappingElement = ConstructMappingElement(); var entityContainerMappingElement = ConstructEntityContainerMapping(edmItemCollection, csdlNamespace); entityContainerMappingElement.Add(ConstructEntitySetMappings(edmItemCollection, csdlNamespace)); entityContainerMappingElement.Add(ConstructAssociationSetMappings(edmItemCollection, csdlNamespace, targetFrameworkVersion)); mappingElement.Add(entityContainerMappingElement); var serializedMappingElement = String.Empty; try { serializedMappingElement = EdmExtension.SerializeXElement(mappingElement); } catch (Exception e) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.ErrorSerializing_CsdlToMsl, e.Message), e); } return(serializedMappingElement as T); }
// TODO perhaps build an in-memory "inference" model that keeps track of the assumptions we make (association/entity type names, etc.) /// <summary> /// Generates store schema definition language (SSDL) based on the provided conceptual schema definition language (CSDL). /// </summary> /// <typeparam name="T"> The type of the activity output. </typeparam> /// <param name="owningActivity"> The currently executing activity. </param> /// <param name="context"> The activity context that contains the state of the workflow. </param> /// <param name="inputs"> Contains the incoming CSDL. </param> /// <returns> Store schema definition language (SSDL) of type T based on the provided conceptual schema definition language (CSDL). </returns> public T GenerateActivityOutput <T>( OutputGeneratorActivity owningActivity, NativeActivityContext context, IDictionary <string, object> inputs) where T : class { _activity = owningActivity; // First attempt to get the CSDL represented by the EdmItemCollection from the inputs object o; inputs.TryGetValue(EdmConstants.csdlInputName, out o); var edmItemCollection = o as EdmItemCollection; if (edmItemCollection == null) { throw new InvalidOperationException(Resources.ErrorCouldNotFindCSDL); } var symbolResolver = context.GetExtension <SymbolResolver>(); var edmParameterBag = symbolResolver[typeof(EdmParameterBag).Name] as EdmParameterBag; if (edmParameterBag == null) { throw new InvalidOperationException(Resources.ErrorNoEdmParameterBag); } // Find the ProviderInvariantName parameter var providerInvariantName = edmParameterBag.GetParameter <string>(EdmParameterBag.ParameterName.ProviderInvariantName); if (String.IsNullOrEmpty(providerInvariantName)) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorNoParameterDefined, EdmParameterBag.ParameterName.ProviderInvariantName)); } // Find the ProviderManifestToken parameter var providerManifestToken = edmParameterBag.GetParameter <string>(EdmParameterBag.ParameterName.ProviderManifestToken); if (String.IsNullOrEmpty(providerManifestToken)) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorNoParameterDefined, EdmParameterBag.ParameterName.ProviderManifestToken)); } // Find the TargetVersion parameter var targetFrameworkVersion = edmParameterBag.GetParameter <Version>(EdmParameterBag.ParameterName.TargetVersion); if (targetFrameworkVersion == null) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorNoParameterDefined, EdmParameterBag.ParameterName.TargetVersion)); } // Find the DatabaseSchemaName parameter var databaseSchemaName = edmParameterBag.GetParameter <string>(EdmParameterBag.ParameterName.DatabaseSchemaName); if (String.IsNullOrEmpty(databaseSchemaName)) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorNoParameterDefined, EdmParameterBag.ParameterName.DatabaseSchemaName)); } DbProviderManifest providerManifest = null; try { providerManifest = DependencyResolver.GetService <DbProviderServices>(providerInvariantName).GetProviderManifest(providerManifestToken); } catch (ArgumentException ae) { // This can happen if the ProviderInvariantName is not valid throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorProviderManifestEx_ProviderInvariantName, providerInvariantName), ae); } catch (ProviderIncompatibleException pie) { // This can happen if the ProviderManifestToken is not valid throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorProviderManifestEx_ProviderManifestToken, providerManifestToken), pie); } if (providerManifest == null) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, Resources.ErrorCouldNotFindProviderManifest, providerInvariantName, providerManifestToken)); } // Resolve the SSDL namespace _ssdlUri = SchemaManager.GetSSDLNamespaceName(targetFrameworkVersion); _ssdl = _ssdlUri; // Resolve the ESSG namespace _essgUri = SchemaManager.GetEntityStoreSchemaGeneratorNamespaceName(); _essg = _essgUri; var csdlNamespace = edmItemCollection.GetNamespace(); var ssdlNamespace = String.IsNullOrEmpty(csdlNamespace) ? "Store" : csdlNamespace + ".Store"; var schemaElement = ConstructSchemaElement(providerInvariantName, providerManifestToken, ssdlNamespace); var entityContainerElement = ConstructEntityContainer(edmItemCollection, databaseSchemaName, csdlNamespace, ssdlNamespace); schemaElement.Add(entityContainerElement); var entityTypes = ConstructEntityTypes(edmItemCollection, providerManifest, targetFrameworkVersion); schemaElement.Add(entityTypes); var associations = ConstructAssociations(edmItemCollection, ssdlNamespace); schemaElement.Add(associations); var serializedSchemaElement = String.Empty; try { serializedSchemaElement = EdmExtension.SerializeXElement(schemaElement); } catch (Exception e) { throw new ArgumentException( String.Format(CultureInfo.CurrentCulture, Resources.ErrorSerializing_CsdlToSsdl, e.Message), e); } return(serializedSchemaElement as T); }