Pergunta

Eu tenho uma aplicação web que compreende o seguinte:

  • projeto web A (com um arquivo web.config que contém uma seqüência de conexão - mas nenhum código de acesso de dados no projeto web)
  • Um projeto de acesso a dados que as classes usos LINQ-SQL para fornecer entidades para a interface do usuário do projeto web (este projeto tem um arquivo de configurações e um app.config - sendo que ambos têm seqüências de conexão)

Quando eu construir e implementar, não há nenhum arquivo de configurações ou app.config no diretório Bin com o acesso .dll de dados, mas mudando a seqüência de conexão no arquivo web.config não altera o banco de dados de conformidade - de modo que o seqüência de conexão deve ser compilado no dll acesso a dados.

O que eu preciso é um arquivo de configuração para toda a minha implantação - site, dlls de acesso a dados, tudo - que tem uma seqüência de conexão que é usada. No momento, parece haver várias cadeias de conexão para se acostumar ou codificado em todo o lugar.

Como faço para melhor resolver esta confusão?

Obrigado por qualquer ajuda.

Foi útil?

Solução

Eu nunca tive um problema com o Acesso a Dados Camada (DAL) ser capaz de usar as seqüências de conexão do meu arquivo web.config. Normalmente eu só copiar seção a conexão cordas da DAL e colá-lo no web.config. Estou usando o designer DBML para criar o contexto de dados.

Se isto não vai funcionar para você, você pode especificar a seqüência de conexão no construtor contexto de dados. Em seu projeto web tem uma classe estática que carrega suas configurações, incluindo as suas cadeias de conexão, e quando você criar seu objeto DAL (ou dados de contexto, se criá-la diretamente) apenas passá-lo para o construtor.

public static class GlobalSettings
{
    private static string dalConnectionString;
    public static string DALConnectionString
    {
       get
       {
           if (dalConnectionString == null)
           {
              dalConnectionString = WebConfigurationManager
                                      .ConnectionStrings["DALConnectionString"]
                                        .ConnectionString;
           }
           return dalConnectionString;
       }
    }
}
...

using (var context = new DALDataContext(GlobalSettings.DALConnectionString))
{
   ...
}

Outras dicas

O arquivo de configuração para o projeto de inicialização irá definir as definições de configuração para todos os projetos incluídos. Por exemplo, se o seu projeto web é o projeto de inicialização, qualquer referência a "appSettings" vai olhar para as configurações de web.config, isso inclui quaisquer referências a "appSettings" de seu projeto de acesso a dados. Então copiar quaisquer definições de configuração de app.config do projeto de acesso a dados para web.config do projeto web.

Roll seu próprio ConnectionFactory com base no Registro:

  • adicionar uma chave de registro para sua aplicação sob SOFTWARE / [YOUR_COMPANY] / [YOUR_APP]
  • adicionar um valor de string para ConnectionString
  • Ensine seu ConnectionFactory de se abrir a chave do registro apropriado (em um construtor estático, não cada carregamento da página!).
  • exportar a informação de registro como um arquivo reg, adicioná-lo ao controle de origem, modificar e aplicá-lo conforme necessário para configurar máquinas adicionais.

Pro:

  • Simples de configurar
  • connectionString vive em um único lugar
  • Não na web / app.config, por isso não há necessidade de configurações específicas do ambiente de codificar.
  • Não na web / config, então júnior Dev Jimmy não pode acidentalmente dizer ao seu servidor de produção a olhar para o banco de dados DEV

Con:

  • Não imediatamente óbvio que coisas importantes estão vivendo no registro, para novos devs vai precisar de instruções.
  • etapa extra ao configurar uma nova máquina implantação
  • Registry é oldskool. devs júnior vai zombar de você.

Obrigado pelas respostas.

Aqueles que dizem que o aplicativo irá usar a configuração no web.config estão corretas para casos em que eu fazem referência a ele em meu próprio código:

_connectionString = ConfigurationManager.AppSettings["ConnectionString"];

.. mas há um problema diferente com datacontexts LINQ-SQL - Eu acho que eles incluem conexões cordas na dll compilado para uso no construtor sem parâmetros. Como tvanofosson diz, eu preciso criar datacontexts passando em uma referência para a seqüência de conexão no web.config. Que é onde eu estava me metendo um emaranhado:)

Eu tinha um pouco de uma luta com esta questão também. I encontrada uma solução através da utilização c # definição de classe parcial e estendendo-se a dados de contexto criado por dbml desenhador. Esta solução bastante é semelhante a resposta de tvanfosson. O que você tem a fazer é criar classe datacontext parcial com construtor padrão recebendo ConnectionString de configurações e em dbml designer de propriedades DC conexão com nenhum set. Essa seqüência de conexão caminho não vai ser o compilados em DLL. Datacontext irá receber automaticamente seqüência de conexão das configurações web.config connectionstring. Eu não testei se isso funciona com app.config também, mas acho que ele deve funcionar bem.

Aqui está amostra de classe parcial DC:

namespace MyApplication {
    /// <summary>
    /// Summary description for MyDataContext
    /// </summary>
    /// 
    public partial class MyDataContext
    {
        public MyDataContext() :
            base(global::System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString, mappingSource)
        {
            OnCreated();
        }
    }
}

O aplicativo usará apenas as entradas de configuração no arquivo web.config. Você pode colocar dll definição de configuração no arquivo web.config, enquanto eles são a estrutura adequada. Meu exemplo é VB específica usando o namespace My, mas dá-lhe a idéia geral.

No configSections Paret do arquivo de configuração que você vai precisar de uma entrada:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="YourAssembly.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup></configSections>

Em seguida, na parte applicationSettings do arquivo de configuração que você colocar as entradas para cada dll:

    <applicationSettings>
      <YourAssembly.My.MySettings>
        <setting name="DebugMode" serializeAs="String">
            <value>False</value>
        </setting>
      </YourAssembly.My.MySettings>
    </applicationSettings>  

Para mantê-lo a salvo de qualquer coisa no código gerado automaticamente, substituir as informações de conexão no método OnCreated () do contexto de dados:

using System.Configuration;
namespace MyApplication 
{
    partial void OnCreated()
    {
        // attempt to use named connection string from the calling config file
        var conn = ConfigurationManager.ConnectionStrings["MyConnectionString"];
        if (conn != null) Connection.ConnectionString = conn.ConnectionString;
    }
}

Desta forma, o designer dbml pode fazer coisas conexão seu caminho (o que não é bom fora de um projeto web), mas você tomar o controle final da conexão quando o aplicativo é executado.

Aqui está uma maneira de olhar para ele. Que componente deve tomar a decisão sobre qual banco de dados para usar? É possível que o banco de dados (ou pelo menos a seqüência de conexão) poderia mudar no futuro. Será que o site decidir qual banco de dados para usar? Ou, se o DAL decidir?

Se você tem dev, bancos de dados de QA, UAT e Prod, gestão destas seqüências de conexão é crucial.

Se o site decide, ele deve passar a seqüência de conexão do seu web.config para o DAL. Se o site não é suposto saber ou se importar onde vêm os dados, em seguida, a seqüência de conexão pertence ao DAL.

Como sobre a definição de um objeto ConnectionFactory, que leva uma enumeração como um parâmetro e retorna um objeto de conexão totalmente formada?

Você também pode ter a aplicação web fornecer a seqüência de conexão quando ele precisa usar o projeto de acesso a dados. Você poderia torná-lo parte do construtor.

Além disso, você poderia poderia apenas escrever sua própria lógica para carregar uma seqüência de conexão de um arquivo externo quando o projeto de acesso de dados torna de chamadas.

Em um mundo perfeito, eu acho que você iria refatorar você camada de dados para pegar configurações através System.Configuration ou construtores / fábricas relevantes. Ou seja, você quer necessidade de reprogramar a sua fonte de configuração implícita ou explicitamente definidas as conexões de seu hospedeiro / consumidor. Outro padrão relacionado para centralizar esses tipos de constantes é jogar uma propriedade somente leitura em uma classe auxiliar estática e ter essa classe gerenciar a resolução real de configurações, etc.

Um lugar que você pode olhar que eu acho que mostra bons exemplos de como fazer isso elegantemente é NHibernate e sua / gestão mapeamentos de configuração. Concedido, que é um pouco do inferno xml, e fluente NHib é mais açucarado, mas a maioria das amostras do mundo real irá mostrar-lhe como conciliar configuração de um suporte de montagem contra a execução de montagem.

Roll seu próprio ConnectionFactory baseado em ficheiros.config:

  • Definir uma seção de configuração personalizada para mapear chave / connectionstring pares
  • Ensine seu ConnectionFactory para farejar em que a seção de configuração utilizando o nome do host ou machinename conforme apropriado
  • chave Populate / connectionstring valores para seus diversos servidores dev / qa / prod, e deixá-los em seus vários app.config, arquivos web.config etc.

Pro:

  • Todas as vidas dentro do projeto, por isso não surpreende
  • Adicionar destino de implementação adicional é um copy / paste operação em um arquivo .config

Con:

  • Faz para grandes seções XML feias, especialmente se você tem servidores dúzia de produção
  • Precisa ser duplicada entre os projetos
  • Precisa de alteração de código e redeploy para adicionar novo alvo
  • Código precisa saber sobre o ambiente em que ele vai viver

Eu sei que este é antiga, mas aqui está como eu faço isso (eu gosto bastante @ maneira de Seba, mas eu não tentei isso)

Este assume suas reside arquivo DBML em sua própria biblioteca de classes, o que eu achei mais conveniente ao compartilhar entidades e acesso a dados em vários sites e outras bibliotecas de classes. Ele também pressupõe que você tenha chamado sua seqüência de conexão o mesmo em cada projeto. Eu uso NAnt para definir isso quando eu implantar a diferentes ambientes.

Eu baseei este na resposta superior acima de @tvanfosson -. Elogios para aquele cara

  1. Crie a sua própria classe base, que deriva do LinqDataContext

Aqui está o código VB:

    Imports System.Configuration

Public Class CustomDataContextBase
    Inherits System.Data.Linq.DataContext
    Implements IDisposable

    Private Shared overrideConnectionString As String

    Public Shared ReadOnly Property CustomConnectionString As String
        Get
            If String.IsNullOrEmpty(overrideConnectionString) Then
                overrideConnectionString = ConfigurationManager.ConnectionStrings("MyAppConnectionString").ConnectionString
            End If

            Return overrideConnectionString
        End Get
    End Property

    Public Sub New()
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String)
        MyBase.New(CustomConnectionString)
    End Sub

    Public Sub New(ByVal connectionString As String, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

    Public Sub New(ByVal connection As IDbConnection, ByVal mappingSource As System.Data.Linq.Mapping.MappingSource)
        MyBase.New(CustomConnectionString, mappingSource)
    End Sub

End Class
  1. Abra o arquivo DBML, e nas Propriedades, adicione o nome da classe acima à propriedade classe base.

Note, se você colocou o costume classe de contexto de dados no mesmo conjunto, basta incluir o nome da classe, por exemplo, CustomDataContext.

Se eles estão em diferentes conjuntos, utilizar o nome completo, por exemplo MyCo.MyApp.Data.CustomDataContext

  1. Para garantir o material Designer funciona corretamente, copie a seqüência de conexão no arquivo app.config para a biblioteca de classes. Isso não vai ser utilizado para além de no IDE.

É isso.

Você vai precisar para nomear sua seqüência de conexão o mesmo

O que você está fazendo essencialmente está forçando o contexto de dados para ignorar o conjunto de informações de conexão no arquivo DBML. Usando os métodos ConfigurationManager significa que ele vai pegar a cadeia de ligação do ligando de montagem.

HTH

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top