ADO.NET Data Services for Multiple Databases?

Silverlight Logo

This all started with an innocent question by Bob Archer on Twitter. Bob wondered whether he could use ADO.NET Data Services in an application that was being touted as "Software as a Service" (SaaS). His concern was the apparent hard wiring of the Data Source in the DataService definition. This design might assume that you had to connect to a single database for all requests.

In his case, the Entity Framework metadata was the same but the connection string might choose a different physical server and database name. I thought that it shouldn't be too difficult. My first attempt to help him was to suggest interceptors for every entity type and manually change the database string based on some data in the request. This felt hacky so I asked Pablo Castro (at Microsoft) for some advice on the problem. He of course had the solution.

The solution was to override the protected CreateDataSource method on the Service. This method is called during each request to create the Data Source. This happens in the pipeline after the request information has been parsed so you can use request parameters to decide what Data Source to create.  You still need to return a Data Source that is the same type as the generic parameter but this means you can determine how to create the object. For example:

public class ProductService : DataService<ProductEntities>
{
  // ...

  protected override ProductEntities CreateDataSource()
  {
    HttpRequest req = HttpContext.Current.Request;

    if (req.IsAuthenticated)
    {
      return new ProductEntities("Authenticated DB Connection String");
    }
    else
    {
      return new ProductEntities("Anonymous DB Connection String");
    }
  }

}

This sample shows that you would need to return a ProductEntities data source, but you can determine how the creation of the data source happens. In the case of how ADO.NET Data Services works, this is called on each and every request separately and not cached so you can safely create a data source based on your current request as shown above.  Thanks Pablo, you made me look good again!

Comments:

Gravatar

Still, I view the entity framework as demoware only at the moment. The fact that the IDE designer *has* to have the model wired to a database. The pattern should be encouraging a single conceptual model (CSDL) and multiple physical data sources, not just databases but other web services, mainframes, vendor APIs etc...

Gravatar

Joe,

The real story here is how ADO.NET Data Services work with multiple databases if needed...it doesn't matter if its Entity Framework, LINQ to SQL, NHibernate, etc. Any LINQ provider.

Gravatar

Shawn, thanks for clearing the trees, so Joe could see the forest(lol).

Gravatar

Right, sorry - just grumbling about the Entity Framework.

Gravatar

The entity framework is, in its current state, not a very flexible product for n-tier solutions.

Gravatar

Kevin,

While i agree about the problem of n-Tier, the point of the post is to show how ADO.NET Data Services (which works with any LINQ-enabled provider) can change connection strings or other properties of the Data Source on each request.

Gravatar

"The fact that the IDE designer *has* to have the model wired to a database."

This statement is not correct. You are perfectly able to create entities in the designer that are not mapped in any way.

Then again, it's not very useful until you do infact map it.

BOb

Gravatar

Bob - is that true?
You can create entities, but the designer will complain at compile time that there are missing mapping entries. Did I miss something?

Gravatar

You can create entities in the designer, what you can't have are partially mapped entities.

Gravatar

Hi Shawn, when I run this code HttpContext.Current is null. Do you have any idea what might be wrong?

Gravatar

The example mentioned in article does not execute properly for me - "HttpContext.Current" is null... How can I get to HttpRequest for I want to check http headers?

Gravatar

Thanks for doing all the leg work. This snippet of of code is exactly what I was looking for. You'd think MS would document this a little better. Thanks again.

Gravatar

I'll take a look at why the HttpContext is null, probably too early in the cycle. Let me take a look.

Gravatar

How can I pass, let's say, from a silverlight application, the database name to connect to?


 



 
Save Cancel