2012-02-06 42 views
2

アプリケーションをデバッグすると、SelectCommand.Connectionプロパティが初期化されていないというエラーが発生します。私はここで何をしているのか分からない。私は実際にテキストボックスのtextchangedイベントで検索してフィルタを追加したいと思っています。SellectCommad.connectionプロパティが初期化されていません

あなた cn変数が nullで、初期化され得ていないためだ
public class ConnectionClass 
{ 
    static SqlConnection cn; 

    public static SqlConnection Connection() 
    { 
     string myConnection = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString; 
     if (cn != null) 
     { 
      cn = new SqlConnection(myConnection); 
      cn.Open(); 
     } 
     return cn; 
    } 

}  

public class ClassDataManagement 
{ 
    SqlConnection cn = ConnectionClass.Connection(); 

    public DataTable GetData(string SQL) 
    { 
     SqlCommand cmd = new SqlCommand(SQL, cn); 
     SqlDataAdapter da = new SqlDataAdapter(cmd); 
     DataTable dt = new DataTable(); 
     da.Fill(dt); 
     return dt; 
    } 
} 

protected void TextBoxFilterText_TextChanged(object sender, EventArgs e) 
{ 
    ClassDataManagement dm = new ClassDataManagement(); 
    string query = "Select CourseCode from _Courses where coursecode like'%" + TextBoxFilterText.Text.TrimEnd() + "%'"; 
    dm.GetData(query); 
    GridViewCourses.DataBind(); 
} 
+6

SQLインジェクションの脆弱性があります。パラメータを使用してください。それとは別に、あなたは接続を決して閉じていないので、「接続が多すぎます」という例外が出るかもしれませんが、確かにパフォーマンスが低下します。静的フィールドに接続を保存しないほうがよいでしょう。オンデマンドで接続オブジェクトを作成し、接続プーリングが接続を管理できるようにします。 http://msdn.microsoft.com/en-us/library/8xx3tyca.aspx –

+0

時には、OPが.configファイルにそのsqlコードを入れるとどうなるのですか? – MethodMan

+0

@DJ Kraze:申し訳ありませんが、私はあまりよくありません。問題は接続文字列ではなく、このクラス全体です。 ADO.NETでは、(静的な)グローバル接続クラスは、ADO.NETのノー・ゴーの1つです.SqlParametersを使用していない場合は、接続の作成、オープン、使用、終了は短期間で、 (ASP.NETのような)スレッド環境です。 –

答えて

4

。静的メソッドでデータベース接続を初期化して開くことは悪い考えです。 SqlDataAdapterクラスに

public class ClassDataManagement 
{ 
    public DataTable GetData(string SQL) 
    { 
      string YourConnectionString = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString;  
      DataTable dt = new DataTable();    

      using (SqlConnection cn = new SqlConnection(YourConnectionString)) 
      using (SqlCommand cmd = new SqlCommand(SQL, cn)) 
      using (SqlDataAdapter da = new SqlDataAdapter(cmd)) 
      { 
       da.Fill(dt); 
      } 
      return dt; 
    } 
} 

、明示的SqlConnection.Open()を呼び出す必要はありません。

が、これは試してみてください。​​メソッドは、すべての接続の開始と終了を処理します。上記の参照を1として

MSDN Reference on SqlDataAdapter.Fill()

、引用された:

をSELECTステートメントに関連付けられた接続オブジェクトが有効である必要がありますが、それは開いている必要はありません。 Fillが呼び出される前に接続が閉じられている場合は、データを取得して閉じます。 Fillが呼び出される前に接続が開いている場合、接続は開いたままです。

+0

Sharkは接続を破棄するためにも同様にラップすることができましたが、それはスタイルの問題です。 – MethodMan

+0

@DJKRAZE 'SqlDataAdapter.Fill()'は接続の処理を処理すると信じています。 –

+0

ハム私はそれをチェックしなければなりません..あなたを疑うことはありませんが、実際に興味がありません。 – MethodMan

2

はそれが

if (cn == null) 
{ 
    cn = new SqlConnection(myConnection); 
    cn.Open(); 
} 
+0

いいえ.. @Sharksの例を見てください。パブリックメソッドではなく静的でなければなりません。答えは良い点ですが、彼の例はさらに優れています。私はあなたの答えをノックしていません。独自のカスタム接続クラス/データコネクタクラスを作成します。 – MethodMan

+0

@DJKRAZEはそれを見ました。ありがとう! – antar

+0

OPの問題を修正します。静的クラスはここでは悪い考えですが、動作します。 –

3

オープン接続とすることが、できるだけ早く閉じてはいけません。あなたの現在の問題を解決するために、すべての与えられたアドバイスを持つ

public DataTable GetData(string commandString) 
    { 
     var result = new DataTable(); 

     using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString)) 
      using (var cmd = new SqlCommand(commandString, cn)) 
       using (var da = new SqlDataAdapter(cmd)) 
       { 
        da.Fill(result); 
       } 

     return result; 
    } 
+1

+1ここで唯一のまともな答えは少なくとも問題のほとんどを解決するためです。 – NotMe

0

、あなたもこの方法を試してください:

public class ConnectionClass 
{ 
static SqlConnection cn; 

    public static SqlConnection Connection() 
    { 
     string myConnection = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString; 

     return new SqlConnection(myConnection); 
     } 
    }  

public class ClassDataManagement 
{  
public DataTable GetData(string SQL) 
    { 
    using (SqlConnection cn = ConnectionClass.Connection()) 
    { 
    //SqlCommand cmd = new SqlCommand(SQL, cn); 
    SqlDataAdapter da = new SqlDataAdapter(SQL,cn); 
    DataTable dt = new DataTable(); 
    da.Fill(dt); 
    return dt; 
    } 
    } 
...... 
+0

nuux、どこでcnすなわち接続文字列を取得していますか?そこに完全な関連コードを入れる必要があります。そうでなければ、このサイトの他のユーザーが解決策としてその答えを見るかもしれません。 – MethodMan

+0

ありがとう@DJKRAZE! – Mubarek

+0

問題ではなく、誰かがあなたの応答を下降させないようにしてください。 – MethodMan

1

セバスチャンの答えが間違っているかのかなりの部分をカバーしていますが。ここに、より完全なリストがあります。

  1. SQLインジェクションの問題があります。すべてのクエリをパラメータ化する必要があります。特に、ユーザーが入力したテキストを直接追加する場合。

  2. リソースが漏れています:SqlConnectionSqlCommandです。これらは、できるだけ実際に接続とコマンドを使用するコードに近い必要があります。私を信頼してください.Windowsは、接続プールでのビルドを通して、すべてのオープン/クローズ接続を処理することができます。あなた自身でこれを維持する必要はありません。

  3. 表示レイヤーに埋め込みSQLが使用されているため、コード自体が脆弱です。たとえば、CourseCodeの名前がCourseIdに変更されたとします。その変更を行うために、多くのコードファイルを検索して変更する必要があります。この問題への露出を制限する方法は複数あります。私はあなたに研究のためにそれを残すでしょう。

野生でこのコードを実行した場合は、全体でConnectionClassが削除されます。もっと頑強な方法で他の場所でやってはいけない、あなたのためにやることは何もありません。

次は、GetData()メソッドを削除します。それはちょうど悪いコードです。あなたは決して完全なSQL文字列を受け入れて、それを盲目的に実行すべきではありません。その1ブロックのコードには、多くのセキュリティ問題があります。

次に、私のSQL(本当に埋め込まれたままにしておきたい場合は、私がそうしないためにはない)がすべてのクエリのコンテナであるように、ClassDataManagementを書き直します。 GetCourseByCourseCode(String courseCode)のような良いメソッドがあり、courseCodeが期待される形式であることを検証し、sqlcommandオブジェクトにクエリのパラメータとして渡します。

ボーナスポイントについては、キャッシュされたデータによってどのような呼び出しがうまく機能するかを調べることで上記を拡張します。それらを特定された方法で実現することで、キャッシュから得られるものと、実際にネットワークを横断してクエリを実行する必要があるものを選ぶことがずっと簡単になります。

次に、私はどこでもSQL呼び出しを行いました。私はSqlConnection、SqlCommand、およびreadersを使用して節をラップしました。メソッドを終了する前に、すべてが適切に閉じられて処分されるようにするのが最良の方法です。何も少ないとあなたはトラブルを招いています。

最後に、データアクセスにEnterprise Libraryを使用することを強く検討します。はるかに良いです。

0
public DataTable GetData() 
{ 
    using (System.Data.SqlClient.SqlConnection con = new SqlConnection("YourConnection string")) 
    { 
     con.Open(); 
     using (SqlCommand cmd = new SqlCommand()) 
     { 
      string expression = "Parameter value"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.CommandText = "Your Stored Procedure"; 
      cmd.Parameters.Add("Your Parameter Name", 
         SqlDbType.VarChar).Value = expression; 
      cmd.Connection = con; 
      using (SqlDataAdapter da = new SqlDataAdapter(SQL, cn)) 
      { 
       DataTable dt = new DataTable(); 
       da.Fill(dt); 
       return dt; 
      } 
     } 
    } 
} 
関連する問題