Wednesday, March 17, 2010

Like I need another connectionstring

One of the annoyances with Entity Framework v1 is that it requires a specialized connection string. This is particularly annoying if you are introducing EF to an existing code base that already uses ADO.NET in some capacity. If you are, you already have a connection string in your app.config, web.config or machine.config that looks like this:

<connectionStrings>
    <add name="EFDb" connectionString="Data Source=.;Initial Catalog=EF;Integrated Security=True"/>   
</connectionStrings>

Now say you want to create an Entity Model against the same database. When you create that model you get a second connection string for EF.

<connectionStrings>
<add name="EFDb" connectionString="Data Source=.;Initial Catalog=EF;Integrated Security=True"/>
<add name="EFEntities" connectionString="metadata=res://*/NoConnectDb.csdl|res://*/NoConnectDb.ssdl|res://*/NoConnectDb.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=.;Initial Catalog=EF;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
</connectionStrings>

Strings attached
This new connection string gives you some ‘metadata’ gobbledygook plus the “provider connection string” which is a duplication of the connection string information already present in your ADO.NET connection string. As far as I can tell, this is just unnecessary connection string proliferation, and another deployment setting to manage and keep in sync. It’d be nice if the EF connection string could just get its info from the ADO.NET connection string by referencing it like:

<add name="EFEntities" connectionString="metadata=res://*/NoConnectDb.csdl|res://*/NoConnectDb.ssdl|res://*/NoConnectDb.msl;provider=System.Data.SqlClient;provider connection string=EFDb" providerName="System.Data.EntityClient" />

I’m not sure if a facility like this exists, I couldn’t find how to do it if it does. Regardless, if I could do something like this, wouldn’t it make that very same EF connection string superfluous? The metadata portion is pretty static, so I’m not sure why that’s stored in configuration to begin with, and if the database connection info is already stored in another setting, what’s the point, why not just get rid of it entirely?

Good riddance

As it turns out, that’s pretty easy to do. This isn’t the only way, but the one that happened to best suit my needs. I inherited from the ObjectContext generated by the model, and then built the Entity Connection String by concatenating the static metadata portion with the pre-existing connection string in the ContextWrapper constructor.

public class ContextWrapper : EFEntities
{
private const string CONNECTION_STRING = "metadata=res://*/NoConnectDb.csdl|res://*/NoConnectDb.ssdl|res://*/NoConnectDb.msl;provider=System.Data.SqlClient;";

public ContextWrapper()
: base(new EntityConnectionStringBuilder(CONNECTION_STRING){ProviderConnectionString = ConfigurationManager.ConnectionStrings["EFDb"].ConnectionString + ";MultipleActiveResultSets=True;"}.ConnectionString){}
}

As long as I use the ContextWrapper instead of the EFEntities objectcontext when working with the model, I don’t need the Entity Connection string in my config at all.

4 comments:

  1. What if you're calling from a different assembly? Won't you need it in the calling assembly?

    ReplyDelete
  2. Not sure what you mean. What do you expect to need in the calling assembly? The "EFDb" connection string?

    ReplyDelete
  3. Yeah, won't you need that EFDb connection string in the calling assembly's config file?

    ReplyDelete
  4. Ah, ok, well maybe it wasn't clear from my post (or the connectionstring named EFDb was misleading), but the assumption is that you already have a connectionstring for your typical ADO.NET code. If you already have code the uses ADO.NET you have an existing connectionstring. EntityFramework uses a different connectionstring even if both EF and ADO.NET are connecting to the same database with the same credentials. This particular solution is to solve that problem. By letting EF re-use the existing ADO.NET connectionstring you don't have duplicates. As for needing the connectionstring in the calling assembly, the connectionstring needs to be configured in the config file for the calling process. That can be a web.config or an app.config. Additionally you could place it in the machine.config for it to be server-wide.

    ReplyDelete