Same EDMX file for different Providers

风流意气都作罢 提交于 2019-12-05 17:34:43

We have the exact scenario working on a production application. We used a T4 template to generate a SQLCE EDMX file based on a canonical SQL EDMX file. This leaves you with 2 EDMX files which you can switch between when instantiating your single context....

    serverType = "sqlserverce" (or) "sqlserver";
    var entityBuilder = new EntityConnectionStringBuilder
    {
        Provider = ...,
        ProviderConnectionString = ...,
        Metadata = string.Format("res://*/{0}.{1}.csdl|res://*/{0}.{1}.ssdl|res://*/{0}.{1}.msl", EdmxName, serverType)
    };

The SQLCE EDMX T4 code looks like this...

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".edmx" #>
<#@ assembly name="System.Xml.dll" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #>
<#
 var document = new XmlDocument();
 document.Load(this.Host.ResolvePath("DbContext.edmx"));

 var namespaceManager = new XmlNamespaceManager(document.NameTable);
 namespaceManager.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");
 namespaceManager.AddNamespace("ssdl", "http://schemas.microsoft.com/ado/2009/02/edm/ssdl");

 var storageModelsNode = document.SelectSingleNode("//edmx:StorageModels", namespaceManager);

 foreach (XmlElement schemaNode in storageModelsNode.SelectNodes("ssdl:Schema", namespaceManager))
 {
     schemaNode.SetAttribute("Provider", "System.Data.SqlServerCe.4.0");
     schemaNode.SetAttribute("ProviderManifestToken", "4.0");

     foreach (XmlElement propertyNode in schemaNode.SelectNodes("ssdl:EntityType/ssdl:Property[@Type='varbinary(max)']", namespaceManager))
     {
         propertyNode.SetAttribute("Type", "image");
     }

     foreach (XmlElement propertyNode in schemaNode.SelectNodes("ssdl:EntityType/ssdl:Property[@Type='varchar']", namespaceManager))
     {
         propertyNode.SetAttribute("Type", "nvarchar");
     }
 }

 var stringBuilder = new StringBuilder();

 using (var stringWriter = new StringWriter(stringBuilder))
 using (var xmlWriter = new XmlTextWriter(stringWriter) { Formatting = Formatting.Indented })
 {
     document.WriteTo(xmlWriter);
 }

 Write(stringBuilder.ToString());
#>

I have found a solution which is described over here: http://www.codeproject.com/Articles/309858/Preparing-an-Entity-Framework-model-for-multi-prov

It's not perfect as you have to copy a part (the SSDL) out of the EDMX file. So you need to remember to update this file as soon as you make changes to your EDMX file.

If someone has a better way I'm still open for it.

This can be done by keeping different copies of the SSDL, as mentioned in the other answer, but it's usually much easier to do it with Code First. Code First will automatically create the different models based on the connection being used. So you just need to point the same code at either the SQL CE database or the SQL Server database. No messing with different SSDLs required.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!