// 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); }
internal void ModelFirstVerifierRunner(string csdlArtifactName, Version versionOfCsdl) { UITestRunner.Execute(TestContext.TestName, () => { var workflowFilePath = Path.Combine( VsUtils.GetVisualStudioInstallDir(), @"Extensions\Microsoft\Entity Framework Tools\DBGen\TablePerTypeStrategy.xaml"); EdmItemCollection edmItemCollection; using ( var csdlStream = TestUtils.GetEmbeddedResourceStream("EFDesigner.InProcTests.TestData." + csdlArtifactName + ".csdl")) { edmItemCollection = new EdmItemCollection(new[] { XmlReader.Create(csdlStream) }); } var testName = "ModelFirstVerifier_" + csdlArtifactName; TestPipeline( testName, edmItemCollection, workflowFilePath, versionOfCsdl, args => { // Aggregate the inputs and outputs var ssdlOutput = (string)args.Outputs[EdmConstants.ssdlOutputName]; var mslOutput = (string)args.Outputs[EdmConstants.mslOutputName]; var storeItemCollection = EdmExtension.CreateAndValidateStoreItemCollection( ssdlOutput, EntityFrameworkVersion.Version2, new LegacyDbProviderServicesResolver(), false); // First we need to validate the MSL (the SSDL has already been validated // otherwise the SSDL to DDL step would have failed) new StorageMappingItemCollection( edmItemCollection, storeItemCollection, new[] { XmlReader.Create(new StringReader(mslOutput)) }); var sb = new StringBuilder( new XElement( "StorageAndMappings", XElement.Parse(ssdlOutput, LoadOptions.PreserveWhitespace), new XText(Environment.NewLine + Environment.NewLine), new XComment("Finished generating the storage layer. Here are the mappings:"), new XText(Environment.NewLine + Environment.NewLine), XElement.Parse(mslOutput, LoadOptions.PreserveWhitespace)).ToString()); // Enable the following when we can get the template to run InProc sb.AppendLine().AppendLine().AppendLine("The generated DDL:"); sb.AppendLine(ScrubDdl((string)args.Outputs[EdmConstants.ddlOutputName])); return(sb.ToString()); }); }); }
protected override void Execute(NativeActivityContext context) { var edmItemCollection = CsdlInput.Get(context); 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.ToString())); } // Validate the TargetVersion parameter if (false == EntityFrameworkVersion.IsValidVersion(targetFrameworkVersion)) { throw new InvalidOperationException( String.Format(CultureInfo.CurrentCulture, Resources.ErrorNonValidTargetVersion, targetFrameworkVersion)); } // Construct the Code View inputs in a dictionary var inputs = new Dictionary <string, object> { { EdmConstants.csdlInputName, edmItemCollection } }; // Process the SSDL and MSL code views, feeding in the CSDL var ssdl = ProcessOutputGenerator <string>(OutputGeneratorType.Get(context), context, inputs); var msl = ProcessOutputGenerator <string>(MslOutputGeneratorType.Get(context), context, inputs); // Validate the SSDL, but catch any naming errors and throw a friendlier one var ssdlCollection = EdmExtension.CreateAndValidateStoreItemCollection( ssdl, targetFrameworkVersion, DependencyResolver.Instance, true); #if DEBUG // Validate the MSL in Debug mode IList <EdmSchemaError> mslErrors; EdmExtension.CreateStorageMappingItemCollection( edmItemCollection, ssdlCollection, msl, out mslErrors); if (mslErrors != null && mslErrors.Count > 0) { var errorSb = new StringBuilder(); errorSb.AppendLine("Encountered the following errors while validating the MSL:"); foreach (var error in mslErrors) { errorSb.AppendLine(error.Message); } Debug.Fail(errorSb.ToString()); } #endif // We are done processing, save off all the outputs for the next stage SsdlOutput.Set(context, ssdl); MslOutput.Set(context, msl); }
// 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); }