Entity Framework Schema Redirection

If your runtime schema differs from your design-time schema, you need to update your Entity Framework metadata to hit your new schema.

Here's a simple solution for doing it at runtime for Entity Framework 4.  I need to update it for EF 5 and 6.

 // Copyright (c) Microsoft Corporation.  All rights reserved
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Xml.Linq;
using System.Xml;
using System.Data.Metadata.Edm;
using System.Data.SqlClient;
using System.Reflection;
using System.Data.EntityClient;
using System.Data.Mapping;
 
namespace EfSchemaRedirection
{
 
  class Program
  {
    static T Connect<T>(string connectionString, string schema) where T : ObjectContext
    {
      var assembly = typeof(T).Assembly;
 
      var rn = assembly.GetManifestResourceNames();
      var ssdl = rn.Single(r => r.EndsWith(".ssdl"));
      var csdl = rn.Single(r => r.EndsWith(".csdl"));
      var msl = rn.Single(r => r.EndsWith(".msl"));
 
      var doc = XDocument.Load(assembly.GetManifestResourceStream(ssdl));
 
      XNamespace ns = "https://schemas.microsoft.com/ado/2009/02/edm/ssdl";
 
      var entitySets = doc.Root
                          .Elements(ns + "EntityContainer").ToList()
                          .Elements(ns + "EntitySet").ToList();
      foreach (var es in entitySets)
      {
        var dq = es.Descendants(ns + "DefiningQuery").FirstOrDefault();
        if (dq != null)  //warning hacking any defining queries is likely to be fragile and require customization.
        {
          XNamespace store = "https://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";
          var designTimeSchema = es.Attribute(store + "Schema").Value;
          dq.Value = dq.Value.Replace("FROM [" + designTimeSchema + "].", "FROM [" + schema + "].")
                             .Replace("JOIN [" + designTimeSchema + "].", "JOIN [" + schema + "].");
        }
        else
        {
          es.SetAttributeValue("Schema", schema);
        }
        
      }
 
      Func<string, XmlReader[]> getFromResource = (name) =>
      {
        using (var s = assembly.GetManifestResourceStream(name))
        {
          return new XmlReader[] { XDocument.Load(s).CreateReader() };
        }
      };
 
      var workspace = new System.Data.Metadata.Edm.MetadataWorkspace();
      var storeItems = new StoreItemCollection(new XmlReader[] { doc.CreateReader() });
      var edmItems = new EdmItemCollection(getFromResource(csdl));
      var mappingItems = new StorageMappingItemCollection(edmItems, storeItems, getFromResource(msl));
 
      workspace.RegisterItemCollection(storeItems);
      workspace.RegisterItemCollection(edmItems);
      workspace.RegisterItemCollection(mappingItems);
      workspace.RegisterItemCollection(new ObjectItemCollection());
 
      workspace.LoadFromAssembly(assembly);
 
      var storeConn = new SqlConnection(connectionString);
 
      ConstructorInfo contextConstructor = typeof(T).GetConstructor(new Type[] { typeof(EntityConnection) });
      var entityConn = new EntityConnection(workspace, storeConn);
      return (T)contextConstructor.Invoke(new Object[] { entityConn });
 
    }
    static void Main(string[] args)
    {
      using (var db = Connect<SchemaTestEntities>(@"server=.;database=SchemaTest;Integrated Security=true","B"))
      {
        var t = db.T.First();
        var vt = db.vts.First();
 
        Console.WriteLine(t.source_schema);
        Console.WriteLine(vt.source_schema);
 
        var sql = string.Format("select * from {0}.[vt]","A");
 
        var vt2 = db.ExecuteStoreQuery<vt>(sql).First();
 
        Console.WriteLine(vt2.source_schema);
      }
 
      
    }
  }
}