문제

데이터베이스 연결 개체를 다른 모듈에 전달하거나 (다른 모듈의) 메서드에서 설정을 처리하도록 하는 것이 권장되는지 궁금합니다.나는 연결을 사용하기 전에 연결 상태를 확인할 필요가 없도록 메서드를 설정하고 호출자가 연결을 설정하는 데 필요한 호출 메서드에 필요한 데이터를 전달하도록 하는 쪽으로 기울고 있습니다.

도움이 되었습니까?

해결책

개인적으로 나는 단단히 범위를 가진 연결을 사용하는 것을 좋아합니다. 늦게 열어서 사용하여 닫으십시오 (로컬 방법 내에서 "사용"블록으로). 연결 풀링은 대부분의 경우 연결 재사용을 처리 하므로이 접근법에는 실질적인 오버 헤드가 없습니다.

연결 통과의 주요 장점 사용된 거래를 통과 할 수 있도록; 하지만, TransactionScope 방법간에 거래를 공유하는 간단한 방법입니다.

클래스는 구현에 따라 다르므로 자체 기본 거래를 열도록 각각 작성합니다. 그렇지 않으면 Ado.net Factory 메소드를 사용하여 구성 파일 (제공자 이름)에서 적절한 유형을 만들 수 있습니다.

다른 팁

개인적으로, 나는 현재 열린 연결과 트랜잭션의 스택을 스레드 로컬 스토리지 setData 및 getData 사용. 데이터베이스에 대한 연결을 관리하고 처분 패턴을 사용할 수있는 클래스를 정의합니다. 이로 인해 연결과 트랜잭션을 통과해야 할 필요성이 줄어 듭니다. 이는 코드를 응고하고 복잡하게 생각하는 것입니다.

강력히 추천합니다 에 맞서 데이터가 필요할 때마다 연결을 열 수있는 방법까지 남겨 둡니다. 응용 프로그램 전체에서 트랜잭션을 관리하기가 어렵고 너무 많은 연결이 열리고 닫히는 상황이 실제로 나쁜 상황으로 이어질 것입니다 (연결 풀링에 대해 알고 있습니다. 개체를 재사용하려면)

그래서 나는이 라인을 따라 무언가를 갖게됩니다 (완전히 테스트되지 않은).

class DatabaseContext : IDisposable {

    List<DatabaseContext> currentContexts;
    SqlConnection connection;
    bool first = false; 

    DatabaseContext (List<DatabaseContext> contexts)
    {
        currentContexts = contexts;
        if (contexts.Count == 0)
        {
            connection = new SqlConnection(); // fill in info 
            connection.Open();
            first = true;
        }
        else
        {
            connection = contexts.First().connection;
        }

        contexts.Add(this);
    }

   static List<DatabaseContext> DatabaseContexts {
        get
        {
            var contexts = CallContext.GetData("contexts") as List<DatabaseContext>;
            if (contexts == null)
            {
                contexts = new List<DatabaseContext>();
                CallContext.SetData("contexts", contexts);
            }
            return contexts;
        }
    }

    public static DatabaseContext GetOpenConnection() 
    {
        return new DatabaseContext(DatabaseContexts);
    }


    public SqlCommand CreateCommand(string sql)
    {
        var cmd = new SqlCommand(sql);
        cmd.Connection = connection;
        return cmd;
    }

    public void Dispose()
    {
        if (first)
        {
            connection.Close();
        }
        currentContexts.Remove(this);
    }
}



void Test()
{
    // connection is opened here
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 1"))
        {
            cmd.ExecuteNonQuery(); 
        }

        Test2(); 
    }
    // closed after dispose
}

void Test2()
{
    // reuse existing connection 
    using (var ctx = DatabaseContext.GetOpenConnection())
    {
        using (var cmd = ctx.CreateCommand("select 2"))
        {
            cmd.ExecuteNonQuery();
        }
    }
    // leaves connection open
}

자동화 된 테스트 목적으로 일반적으로 전달하기가 더 쉽습니다. 의존성 주입.

테스트를 작성해야 할 때는 모의 데이터베이스 연결 객체를 만들고 실제 대신이를 전달할 수 있습니다. 이렇게하면 자동화 된 테스트는 매번 데이터로 다시 채워야하는 실제 데이터베이스에 의존하지 않습니다.

개인적으로 데이터 액세스를 가능한 한 중앙 집중화하기 위해 노력하지만, 불가능하다면 실제 연결을 통과 할 때 방해가 될 수있는 다른 것들이 너무 많기 때문에 항상 다른 클래스에서 새로운 연결을 열어줍니다. 물체.

이 문제에 대한 조금 더 통찰력이 있습니다. DB 연결을 관리하는 클래스가 있으며 인터페이스를 구현하는 2 개의 클래스가 있습니다. 클래스 중 하나는 SQL이고 다른 하나는 OLAP입니다. 관리자는 사용할 연결을 아는 관리자이므로 유형에 정확한 연결을 전달하거나 유형이 자신의 연결을 생성 할 수 있습니다.

아무런 문제 없이 연결 개체를 전달할 수 있습니다(예를 들어 Microsoft Enterprise Library에서는 연결을 전달하는 정적 메서드 호출을 허용함). 또는 설계에 따라 외부적으로 관리할 수도 있습니다. 직접적인 기술적 절충점은 없습니다.

솔루션이 다른 데이터베이스로 이식될 경우 이식성이 특정 연결을 전달하지 않도록 주의하십시오(즉, 다른 데이터베이스와 작업하려는 경우 SqlConnection을 전달하지 마십시오).

연결을 설정하는 것은 잠재적으로 비싸고 왕복 여행이 추가됩니다. 따라서 잠재적으로 더 나은 디자인은 연결 객체를 통과하는 것입니다.

나는 당신이 Microsoft Ado 앱이라면 아마도 연결 풀을 사용하고 있기 때문에 잠재적으로 말합니다 ....

연결 객체와 그 상태를 구별하는 것이 좋습니다 (열린, 닫힘).

web.config에서 연결 문자열을 읽는 단일 메소드 (또는 속성)를 가질 수 있습니다. 매번 동일한 버전의 연결 문자열을 사용하면 연결 풀링의 혜택을받을 수 있습니다.

연결을 열어야 할 때 해당 메소드를 호출하십시오. 마지막 순간에 모든 SQLCommand 속성을 설정 한 후 연결을 열고 사용한 다음 닫으십시오. C#에서는 사용 명령문을 사용하여 연결이 닫혀 있는지 확인할 수 있습니다. 그렇지 않은 경우 최종 블록에서 연결을 닫으십시오.

web.config를 사용하겠습니다

<configuration>
    <connectionStrings>
        <add name="conn1" providerName="System.Data.SqlClient" connectionString="string here" />
        <add name="conn2" providerName="System.Data.SqlClient" connectionString="string here" />
    </connectionStrings>
</configuration>

그런 다음 응용 프로그램의 어느 곳에서나 참조 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top