Using a random model at runtime

In my last post I hinted that using the Entity Frameworks Value layer and Metadata allows you to work against any Entity Data Model in a loosely coupled way.

Let’s see how…

So let’s imagine you are working against the Value layer. With code something like this:

using (EntityConnection conn = new EntityConnection(conn_str))

{

conn.Open();

}

How do you walk up to any old model at runtime?

Well to do that you need some way of building a connection string. The way I do this in a bunch of my apps is I have a template and I simply merge parameters into it at runtime.

string EDM_CONN_STR_TEMPLATE = @"metadata={csdl}|{ssdl}|{msl};provider={provider};provider connection string=""{provider_connection_string}""";

conn_str = EDM_CONN_STR_TEMPLATE.Replace("{csdl}", csdlPath);

conn_str = conn_str.Replace("{ssdl}", ssdlPath);

conn_str = conn_str.Replace("{msl}", mslPath);

conn_str = conn_str.Replace("{provider}", provider);

conn_str = conn_str.Replace("{provider_connection_string}", providerConnectionString);

Now in all likelihood the {provider} is going to be System.Data.SqlClient and as a result the {provider_connection_string} is just a standard SQL connection string

NB: If you are wondering why I use {name1}{name2} in my template rather than {0}{1} , it is just to make the template a little easier to read!

 Now you’ve done that you can issue any query you want against the connection. The question is what do you query?

Well probably your first step is to get a list of all the EntitySets available… How do you do that?

MetadataWorkspace workspace = conn.GetMetadataWorkspace();

var sets = from container in

workspace.GetItems<EntityContainer>(DataSpace.CSpace)

from set in container.BaseEntitySets

where set is EntitySet

select set;

foreach (EntitySet set in sets)

{

Console.WriteLine("{0} holds instances of {1}", set.Name, set.ElementType.FullName);

}

So what is going on here?

Well first we get the MetadataWorkspace that holds all the information contained in the CSDL, MSL and SSDL files. Then we query for EntitySets inside EntityContainers in that CSpace.

What!? CSpace? EntityContainers? EntitySets?

A little glossary might help:

CSpace: The MetadataWorkspace holds a lot of information, and this is partitioned into various DataSpaces of which CSpace is one. The CSpace basically hold all the information about our Conceptual Model i.e. the Entities and EntitySets described in the CSDL files.

EntityContainer: This is place where we can group EntitySets, note if you use CodeGen the resulting specialized ObjectContext created is based on the EntityContainer, in particular you will find a property which exposes each EntitySet in the EntityContainer.

EntitySet: You can think of this as the EDM equivalent of a database Table. This is where you can actually get your Entities from. A very common question that comes up right about now is:

“Why can’t I just have Entities and query those?”

 Well the idea behind EntitySets is they allow you to have multiple places where a single EntityType can reside, and allow those to be treated independently. However in most simple applications there will probably be a be just one EntitySet per EntityType.

Okay so back to the code:

First we get all EntityContainers from the CSpace, then we get all Sets from the container and then we filter to make sure we have just EntitySets (it could be an AssociationSet… more on that another time).

At this point we have an enumeration of all EntitySets available.

In the next post I explain how we can use that…