The official source of information on Managed Providers, DataSet & Entity Framework from Microsoft
In part one of this series, we looked at our motivation for the series, and we discussed the file differences between EDMX & csdl, ssdl & msl files. In part two, we will discuss generating a model from a database, and generating code from a model.
In Visual Studio, there is a wizard that walks you through the process of connecting to a database, and generating an Entity Data Model from it. The wizard allows you to select the tables, views & stored procedures to include in your EDM model. Similar functionality is available from the command-line:
edmgen.exe /mode:FullGeneration /connectionstring:"Data Source=%ProgramFiles%\Microsoft SQL Server Compact Edition\v3.5\Samples\Northwind.sdf" /provider:System.Data.SqlServerCe.3.5 /project:SqlCENorthwind
The example above doesn’t allow you to select the database objects in the model, and it also does a bit more than generating the model, as it also generates code & views. We’ll describe code generation in more detail below, and we’ll describe view generation in part 3 of this series. For now though, we’ll take a quick look at the APIs to generate a model from a database. In Listing 2, we call the EntityStoreSchemaGenerator and the EntityModelSchemaGenerator. These classes are defined in the System.Data.Entity.Design namespace and are packaged in an assembly of the same name.
The code below generates the ssdl from a database, and then generates the csdl & msl to complete the EDM model. Finally it writes this data into an EDMX file.
private static void ModelGen( string connectionString, string provider, string modelName) { IList<EdmSchemaError> ssdlErrors = null; IList<EdmSchemaError> csdlAndMslErrors = null; // generate the SSDL string ssdlNamespace = modelName + "Model.Store"; EntityStoreSchemaGenerator essg = new EntityStoreSchemaGenerator( provider, connectionString, ssdlNamespace); ssdlErrors = essg.GenerateStoreMetadata(); // write out errors if ((ssdlErrors != null && ssdlErrors.Count > 0)) { System.Console.WriteLine("Errors occurred during generation:"); WriteErrors(ssdlErrors); return; } // write the SSDL to a string StringWriter ssdl = new StringWriter(); XmlWriter ssdlxw = XmlWriter.Create(ssdl); essg.WriteStoreSchema(ssdlxw); ssdlxw.Flush(); // generate the CSDL string csdlNamespace = modelName + "Model"; string csdlEntityContainerName = modelName + "Entities"; EntityModelSchemaGenerator emsg = new EntityModelSchemaGenerator( essg.EntityContainer, csdlNamespace, csdlEntityContainerName); csdlAndMslErrors = emsg.GenerateMetadata(); // write out errors if (csdlAndMslErrors != null && csdlAndMslErrors.Count > 0) { System.Console.WriteLine("Errors occurred during generation:"); WriteErrors(csdlAndMslErrors); return; } // write CSDL to a string StringWriter csdl = new StringWriter(); XmlWriter csdlxw = XmlWriter.Create(csdl); emsg.WriteModelSchema(csdlxw); csdlxw.Flush(); // write MSL to a string StringWriter msl = new StringWriter(); XmlWriter mslxw = XmlWriter.Create(msl); emsg.WriteStorageMapping(mslxw); mslxw.Flush(); // write csdl, ssdl & msl to the EDMX file ToEdmx( csdl.ToString(), ssdl.ToString(), msl.ToString(), new FileInfo( modelName + ".edmx")); }
Listing 2. Code example generating a model from a database. Full code can be downloaded here.
“Code Generation”, in the context of the EDM, refers to the process where we generate classes from the entities & associations defined in your EDMX file. These classes are what give you programmatic access to your data. In Visual Studio, we generate code through a Visual Studio “Single File Generator”. The Single File Generator (SFG) is kicked off whenever the EDMX file is saved, and this causes the “.Designer.cs” (or “.Designer.vb”) code-behind file to be updated. You can also launch the SFG by right-clicking an EDMX file in solution explorer, and choose the “Run Custom Tool” context menu.
To generate code from the command-line, you would use the following command:
edmGen.exe /mode:EntityClassGeneration /incsdl:SqlCENorthwind.csdl /language:CSharp /outobjectlayer:SqlCENorthwind.cs
In Listing 3, we show the code to generate code from an EDMX. This uses the EntityClassGenerator class.
private static void CodeGen(FileInfo edmxFile, LanguageOption languageOption){ XElement c = GetCsdlFromEdmx(XDocument.Load(edmxFile.FullName)); // generate code StringWriter sw = new StringWriter(); EntityClassGenerator codeGen = new EntityClassGenerator(languageOption); IList<EdmSchemaError> errors = codeGen.GenerateCode(c.CreateReader(), sw); // write out code-file string outputFileName = GetFileNameWithNewExtension(edmxFile, GetFileExtensionForLanguageOption(languageOption)); File.WriteAllText(outputFileName, sw.ToString()); // output errors WriteErrors(errors);
}
Listing 3. Code example to run code-gen on an EDMX file. Full code can be downloaded here.
In part three of this four-part series, we will look at the validation and view generation APIs available to validate EDM models, and generate ESql views for models.
Mike KaufmanSoftware Design Engineer