2013-06-04 3 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; 
     } 

} 

в акции Home:

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, но в классе Admin.

Проблема заключается в статической переменной connexion: в первой функции Client_List его значение правильно и я получить список клиентов, но это стало null во второй функции, несмотря на это статическая переменная в статическом классе !! !

В чем причина этого изменения? Как я могу это исправить?

+9

пытается провести ' SqlConnection' открывается в статическом поле, вероятно, является плохой идеей по ряду причин. Скорее всего, это «нуль», потому что он утилизируется после его первого использования. Просто создайте новый 'SqlConnection', когда вам это нужно, и немедленно отпустите его. Не пытайтесь удерживать ресурсы SQL на неопределенный срок. – David

+2

@ Давид +1, очень, очень плохая идея. –

+1

'using (Data.connexion)' - как только ваш первый потребитель использует его, соединение закрывается и удаляется. Как говорит Дэвид, не держите свое соединение - откройте его, когда вам это нужно, закройте его, когда закончите, и не пытайтесь реализовать свой собственный «пул» подключения. – GalacticCowboy

ответ

4

Вы либо устанавливаете connexion в null где-то, либо не инициализируете его, прежде чем использовать его.

Скорее всего, один класс вызывает Disconnect, который устанавливает connexion в значение 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

Ваше используя оператор избавляется от связи с использованием интерфейса IDisposable

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

     using (Data.connexion) <--- here 
} 

Изменить это, чтобы создать новое соединение

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

     using (var connection = Data.CreateConnexion()) 
} 

подобное этому

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; 

    } 
} 
Смежные вопросы