EntityConnection (System.Data.EntityClient.EntityConnection) is the class which provides an abstraction for the connection established by the framework.What exactly we mean by connection established by the framework? A ORM framework stands in between an object model and a data source so it needs to connect to both i.e the model and the data source.
When we add an Entity Data Model (*.edmx) a default connection string gets added to the solution as shown below:
As indicated in the figure above the two critical components, one is metadata (model) and another is provider (datasource). The datasource part is quite obvious and easy to understand so let’s concentrate on the metadata part of it.
The entity data model (*.edmx) contains three xml based sections:
- Storage Model define in Storage Schema Definition Language (SSDL)
- Conceptual Model (Class Model) defined in Conceptual Schema Definition Language(CSDL)
- Mapping defined in Mapping Specification Language(MSL)
By default settings, when the code is compiled these three xml blocks get embedded into the assembly as resources. So in the metadata connection string we need to specify name of the SSDL/MSDL/CSDL and from which assembly we need to download them. This is shown in the figure below:
If we can change the Metadata location to output directory as shown below then SSDL/MSDL/CSDL files will be separately generated in the output (bin) folder
The files will be be generated as shown below:
The connection string gets modified as shown below:
So far so good. Though in most of the cases it seems to me that embedding inside the assembly makes much more sense but some of the configuration crazy crowd might think otherwise as well.So how we can manipulate this programmatically through the API.It’s time to go back to the EntityConnection class.
The EntityConnection class has a constructor which accepts a connection string as shown above containing both database and metadata information.But in case there are many metadata files this will be extremely cumbersome & long.
So to do similar stuff using API we need to see metadata information is exposed through classes.
EntityConnection holds a reference to System.Data.Common.DbConnection & System.Data.Metadata.Edm.MetadataWorkspace as shown in the figure below
MetadataWorkspace is the class representing the metadata and it has the following constructor which accepts list of paths and assemblies.
- public MetadataWorkspace(IEnumerable<string> paths,IEnumerable<Assembly> assembliesToConsider)
The following code block shows how we can use this constructor to read the metadata from file system: Here I have passed null in the second parameter as we are not extracting metadata from assembly here.
This leads to the following ArgumentNullException exception.
{“Value cannot be null.\r\nParameter name: assembliesToConsider”}
However passing a empty list works
static void Main(string[] args) { DbConnection dbc = new SqlConnection(@"data source=.\SQLEXPRESS;initial catalog=AdventureWorksLT2008; integrated security=True;multipleactiveresultsets=True;"); MetadataWorkspace mdw = new MetadataWorkspace(new List<String>() { @"D:\Demos\EFSample\AdventureWorks.Sales\bin\Debug\SalesModel.csdl", @"D:\Demos\EFSample\AdventureWorks.Sales\bin\Debug\SalesModel.ssdl", @"D:\Demos\EFSample\AdventureWorks.Sales\bin\Debug\SalesModel.msl" } ,new List<Assembly>()); AdventureWorksLT2008Entities a = null; try { a = new AdventureWorksLT2008Entities(new EntityConnection(mdw, dbc)); Console.WriteLine(a.ProductCategories.First().Name); } finally { (a as IDisposable).Dispose(); } Console.Read(); }