Как переопределить Sting соединения в автоматически сгенерированном коде модели сущностей - PullRequest
0 голосов
/ 17 марта 2011

Сценарий. Я хочу динамически выбирать строку подключения в зависимости от среды, в которой выполняется приложение.

Среда: у меня есть две среды Dev и Production для службы WCF.Я храню строки подключения в web.config.Когда приложение запускается, задайте переменную с правильной строкой подключения.

Проблема: при создании модели данных создается 2 файла: dmMyDataModel.edmx и dmMyDataModel.Designer.cs, в файле конструктора естьтам конструкторы, которые определяют соединение с EntityDatabas.

В приведенном ниже коде вы можете видеть, что я создал конструктор в сервисе, который при вызове сервиса устанавливает контекст для использования правильной строки соединения.Но только элементы, которые используют myContext, работают правильно (хранимые процедуры), запрос dbMyWebSiteEntities завершается неудачно в производственной среде, поскольку они все еще зависят от строки подключения, установленной в конструкторе.

Я устал устанавливать логику в конструкторе, но она стирается при повторной генерации.

dmMyDataModel.Designer.cs

using System;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Data.EntityClient;
using System.ComponentModel;
using System.Xml.Serialization;
using System.Runtime.Serialization;

[assembly: EdmSchemaAttribute()]

namespace MyWebSite.Services
{
    #region Contexts

    /// <summary>
    /// No Metadata Documentation available.
    /// </summary>
    public partial class dbMyWebSiteEntities : ObjectContext
    {
        #region Constructors

        /// <summary>
        /// Initializes a new dbMyWebSiteEntities object using the connection string found in the 'dbMyWebSiteEntities' section of the application configuration file.
        /// </summary>
        public dbMyWebSiteEntities() : base("name=dbMyWebSiteEntities", "dbMyWebSiteEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }

        /// <summary>
        /// Initialize a new dbMyWebSiteEntities object.
        /// </summary>
        public dbMyWebSiteEntities(string connectionString) : base(connectionString, "dbMyWebSiteEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }
        /// <summary>
        /// Initialize a new dbMyWebSiteEntities object.
        /// </summary>
        public dbMyWebSiteEntities(EntityConnection connection) : base(connection, "dbMyWebSiteEntities")
        {
            this.ContextOptions.LazyLoadingEnabled = true;
            OnContextCreated();
        }

        #endregion
        ...
    }

MyWebSiteData.svc.cs

using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
using System.ServiceModel.Activation;
using System.ServiceModel;
using System.Data.EntityClient;
using System.Configuration;
using System.Data.Objects;

namespace MyWebSite.Services
{
    public class MyWebSiteData : DataService<dbMyWebSiteEntities>
    {
        private dbMyWebSiteEntities myContext;

        public static void InitializeService(DataServiceConfiguration config)
        {
            config.UseVerboseErrors = true; 
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            config.SetEntitySetPageSize("*", 25);

            config.SetServiceOperationAccessRule("mar_getAllByKey", ServiceOperationRights.AllRead);
        }

        //Constructor to override the connection string used in the dmMyDataModel.Designer.cs
        public MyWebSiteData()
        {
            //sets the connetion string and appends the environment so it will pull the correct one from the web.config
            EntityConnection conn = new EntityConnection("name=dbMyWebSiteEntities" + HttpContext.Current.Application["Environment"]);
            myContext = new dbMyWebSiteEntities(conn);
        }

        //This returns the data from the stored procedures
        [WebGet]
        public ObjectResult<myTable> mar_getAllByKey(string key)
        {
            return myContext.mar_getAllByKey(key);
        }
    }
}

Спасибо, что нашли время взглянуть на это.Я пытался быть конкретным и подробным, но если я что-то упустил, дайте мне знать.

Спасибо, Джеральд

Ответы [ 3 ]

4 голосов
/ 17 марта 2011

Сгенерированный класс partial.Если вы хотите добавить новые конструкторы, определите другой частичный класс (с тем же именем класса и пространством имен) в другом файле и добавьте туда свои конструкторы.Ваш файл не будет восстановлен.Для этого и используется ключевое слово * 1002.

Ваш новый конструктор должен быть уникальным - разные параметры.

Вы также можете определить статический метод фабрики в вашем частичном классе, который будет инкапсулировать логикусоздание экземпляров.

Я устанавливаю разные строки подключения в файлах .config, используя преобразования XML для каждой имеющейся у меня среды (Dev / Test / Beta / Prod).

0 голосов
/ 18 марта 2011

Подобный запрос можно найти в более чем здесь

. В нем приведен пример использования класса EntityConnectionStringBuilder в пространстве имен System.Data.Common.DbConnectionStringBuilder

0 голосов
/ 17 марта 2011

Лучший способ - создать обертку:

public static class DBContextCreator
{
   public static MyDBContext Create()
   {
        return new MyDBContext(/* pass in connection of choice here */);
   }
}

В этой оболочке вы можете обрабатывать различные логики различными способами.

НТН.

...