Один и тот же файл EDMX для разных провайдеров

Я работаю над проектом, в котором у меня есть локальная база данных (SQL CE), которая используется как своего рода буфер, а соединение с сервером не существует. На сервере я хочу использовать ту же структуру базы данных.

Конечно, я хочу использовать тот же файл EDMX, который находится в Common.dll, доступном на сервере и клиенте.

В клиенте у меня есть строка подключения с provider = System.Data.SqlServerCe.3.5, в то время как на сервере это provider = System.Data.SqlClient.

Моя проблема возникает, когда я хочу сохранить sth на стороне сервера: "Указанный манифест поставщика не относится к типу System.Data.SqlClient.SqlProviderManifest".

Есть ли шанс использовать один и тот же EDMX-файл на обеих частях? Или есть лучшая практика, как обращаться с таким созвездием?

Спасибо за помощь!

РЕДАКТИРОВАТЬ: Мой главный вопрос: можно ли включить файл EDMX для использования с различными поставщиками? В моем случае System.Data.SqlServerCe.3.5 и System.Data.SqlClient!

3 ответа

Решение

У нас есть точный сценарий, работающий над производственным приложением. Мы использовали шаблон T4 для генерации файла SQLCE EDMX на основе канонического файла SQL EDMX. Это оставляет вам 2 EDMX-файла, между которыми вы можете переключаться при создании единого контекста....

    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)
    };

Код SQLCE EDMX T4 выглядит следующим образом...

<#@ 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());
#>

Я нашел решение, которое описано здесь: http://www.codeproject.com/Articles/309858/Preparing-an-Entity-Framework-model-for-multi-prov

Это не идеально, так как вы должны скопировать часть (SSDL) из файла EDMX. Поэтому вам нужно помнить об обновлении этого файла, как только вы внесете изменения в файл EDMX.

Если у кого-то есть лучший способ, я все еще открыт для этого.

Это можно сделать, сохранив разные копии SSDL, как упоминалось в другом ответе, но обычно это гораздо проще сделать с помощью Code First. Code First автоматически создаст различные модели в зависимости от используемого соединения. Поэтому вам просто нужно указать один и тот же код либо в базе данных SQL CE, либо в базе данных SQL Server. Не нужно возиться с разными SSDL.

Другие вопросы по тегам