2013-06-04 5 views
3

정적 클래스의 asp.net MVC에서 정적 변수 : 액션 홈내가 정적 클래스 데이터가

public static class Data 
    { 
     public static SqlConnection connexion; 


     public static bool Connect() 
     { 
       System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(); 
       builder["Initial Catalog"] = "Upload"; 
       builder["Data Source"] = "base"; 
       builder["integrated Security"] = true; 
       string connexionString = builder.ConnectionString; 
       connexion = new SqlConnection(connexionString); 
       try { connexion.Open(); return true; } 
       catch { return false; } 

     } 
     public static void Disconnect() 
     { 
      if (connexion != null) connexion.Close(); 
      connexion = null; 
     } 

} 

:

public ActionResult Home() 
     { 
      Data.Connect(); 
      if (CompteModels.Connected) 
      { 
       ArrayList model = new ArrayList(); 

       ClientModels clients = new ClientModels(); 
       model.AddRange(clients.Client_List()); 

       AdminModels admins = new AdminModels(); 
       model.AddRange(admins.Admin_List()); 


       return View(model); 
      } 

      else return RedirectToAction("Login", "Account"); 
} 

클라이언트 클래스 :

public List<ClientModels> Client_List() 
     { 
      List<ClientModels> l = new List<ClientModels>(); 

      using (Data.connexion) 
      { 

       string queryString = @"select Login, Password, Mail, Name, Tentatives from Compte where User_type_id in (select Id from User_type where Fonction = 'Client')"; 

       SqlCommand command = new SqlCommand(queryString, Data.connexion); 


       try 
       { 
        SqlDataReader reader = command.ExecuteReader(); 


        do 
        { 

         while (reader.Read()) 
         { 
          ClientModels admin = new ClientModels { Login = reader.GetString(0), Password = reader.GetString(1), Mail = reader.GetString(2), Name = reader.GetString(3), Tentatives = reader.GetInt32(4) }; 
          l.Add(admin); 


         } 
        } while (reader.NextResult()); 

        return l; 



       } 
       catch { return null; } 

      } 

함수의 경우 AdminList 인 경우 구현은 Client_List과 같지만 클래스는입니다..

문제는 정적 변수 connexion에 : 첫 번째 함수에 Client_List 그 값이 정확하고 i는 클라이언트의 목록을 얻을 수 있지만, 정적 클래스의 정적 변수가에도 불구하고 두 번째 기능에 null되고있다! !

이 변경의 이유는 무엇입니까? 어떻게 해결할 수 있습니까?

+9

public List<ClientModels> Client_List() { List<ClientModels> l = new List<ClientModels>(); using (var connection = Data.CreateConnexion()) } 

유사한 새 연결을 만들 수는 IDisposable 인터페이스

public List<ClientModels> Client_List() { List<ClientModels> l = new List<ClientModels>(); using (Data.connexion) <--- here } 

변경을 사용하여 접속을 처분 정적 필드에서 열린 SqlConnection'은 여러 가지 이유로 나쁜 생각 일 수 있습니다. 그것이 처음 사용 된 후에 처리되기 때문에 'null'일 가능성이 큽니다. 필요한 때에 새로운'SqlConnection'을 생성하고 즉시 해제하십시오. 무기한으로 SQL 자원을 보류하지 마십시오. – David

+2

@David +1, 아주 나쁜 아이디어. –

+1

'(Data.connexion) 사용하기'- 첫 번째 소비자가 그것을 사용하자마자 연결이 닫히고 처리됩니다. David가 말했듯이 연결을 유지하지 마십시오. 필요할 때 열거 나 작업을 마칠 때 닫고 자신의 연결 "풀"을 구현하지 마십시오. – GalacticCowboy

답변

4

사용하기 전에 connexion에서 null으로 설정하거나 초기화하지 않았습니다.

대부분의 경우 한 클래스는 Disconnect을 호출하여 connexion을 null로 설정하고 다른 클래스는 null이 아닌 것으로 간주하여 사용하려고합니다.

설명에서 언급했듯이 SqlConnection과 같은 리소스에 정적 참조를 유지하는 것은 좋은 생각이 아닙니다. 당신이 코드를 재사용 할 경우 당신은 SqlConnection 인스턴스를 반환하는 정적 기능를 작성하고 연결 문자열을 만들 수 있습니다 정적하지만 점유율은 줄 것이다 전체 웹 사이트 전체의 연결에 대한 정적 참조를 가진 당신이 가치있는 것보다 더 많은 문제들 (당신이 이미보고있는 것처럼). 정적 함수에서 그것을 할 수

한 가지 방법은 다음과 같습니다

public static SqlConnection GetConnection() 
{ 
    System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(); 
    builder["Initial Catalog"] = "Upload"; 
    builder["Data Source"] = "base"; 
    builder["integrated Security"] = true; 
    string connexionString = builder.ConnectionString; 
    connexion = new SqlConnection(connexionString); 

    return connexion; 
} 

다음과 같이 보일 것입니다 귀하의 클라이언트 코드 :

using (SqlConnection conn = Data.GetConnection()) 
0

다른 사람이 이미 언급 한 바와 같이이, 나쁜 생각 .

당신은 간단하게 작성하고 필요한 경우 연결을 열고 나중에 그것을 폐기해야합니다

물론
using (SqlConnection connection = new SqlConnection(connectionString)) 
{  
    connection.Open(); 
    // ... now use it 
} 

,이 메커니즘을 숨기기 다른 패턴이 있습니다,하지만 귀하의 경우 과잉 될 수 있습니다.

0

귀하의 사용 문이의`를 개최 노력이

public static class Data 
{ 
    public static SqlConnection CreateConnection() 
    { 
     System.Data.SqlClient.SqlConnectionStringBuilder builder = new System.Data.SqlClient.SqlConnectionStringBuilder(); 
      builder["Initial Catalog"] = "Upload"; 
      builder["Data Source"] = "base"; 
      builder["integrated Security"] = true; 
      string connexionString = builder.ConnectionString; 
      var connexion = new SqlConnection(connexionString); 
      connexion.Open(); 
      return connexion; 

    } 
}