0

コードを実行すると、adr のオブジェクトが null であることがわかりますが、それは本当ですが、select ではなく insert を除いて、同じメソッドの複製で機能すると機能しないのはなぜですか。

コードは次のようになります。

public City doesExist(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("select Id from [By] where Postnummer='" + postnr + "' and Navn='" + navn + "'", con))
    {
        command.Connection = con;
        SqlDataReader reader = command.ExecuteReader();
        if (reader.Read())
        {
            city.id = reader.GetInt32(0);
            city.postnr = postnr;
            city.navn = navn;
            reader.Close();

            return city;
        }

        reader.Close();
        return null;
    }
}

public City create(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
    {
        object ID = command.ExecuteScalar();

        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}

呼び出しは次のようになります。

City city = new City();
city = city.doesExist(zip, by, city, connection); // this works fine
if (city == null)
{
     // I know that city is null
     // tried inserting City city = new City(); same error
     city = city.create(zip, by, city, connection); // this is where the null error occours
}
4

3 に答える 3

8

はい、見てください:

if (city == null)
{
    // If we've got in here, we know that city is a null reference, but...
    city = city.create(...);
}

間違いなくnullである参照でメソッドを呼び出しています。をスローすることが保証されていNullReferenceExceptionます。

ほとんどの場合、createメソッドを静的にし (通常の .NET 命名規則に準拠するように名前を変更します)、次のように呼び出します。

city = City.Create(...);

また、メソッド呼び出しからパラメーターを削除し、代わりにメソッドcityに新しいCityオブジェクトを作成する必要があります。例えば:

public static City Create(string postnr, string navn, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand
         ("insert into [By] (Postnummer, Navn) values (@postnr, @navn); "+
          "select @@identity as 'identity';", con))
    {
        command.Parameters.Add("@postnr", SqlDbType.NVarChar).Value = postnr;
        command.Parameters.Add("@navn", SqlDbType.NVarChar).Value = navn;
        object ID = command.ExecuteScalar();

        City = new City();
        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}

パラメータ化されたSQLも使用するようにコードを変更したことに注意してください。本当に、本当に、そのような SQL ステートメントに値を直接入れるべきではありません。システムがSQL インジェクション攻撃にさらされ、さまざまな変換が面倒になります。

さらに、SqlConnectionデータベース操作ごとに新しい を作成する (そして閉じる) ことをお勧めします。

率直に言って、 がインスタンス メソッドであるというのは少し奇妙です... 繰り返しますが、パラメータdoesExistを取るということです。city

CityRepositoryこれの設計を変更して、接続文字列を認識し、公開する (または同様のもの) を作成することをお勧めします。

// I'd rename these parameters to be more meaningful, but as I can't work out what they're
// meant to mean now, it's hard to suggest alternatives.
public City Lookup(string postnr, string nav)

public City Create(string postnr, string nav)

リポジトリは関連する接続文字列を認識し、すべてのデータベース操作を担当します。タイプはCityデータベースについて何も知りません。

于 2013-03-06T13:29:32.687 に答える
0

初期化されていない/null であるオブジェクト クラスのメソッドを呼び出そうとしています。

City.create静的メンバーを作成する必要があります。

public static City create(string postnr, string navn, City city, SqlConnection con)
{
    DatabaseConnection.openConnection(con);
    using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
    {
        object ID = command.ExecuteScalar();

        city.id = Convert.ToInt32(ID);
        city.postnr = postnr;
        city.navn = navn;
        return city;
    }
}

そしてそれを次のように使用します:

if(city==null) 
{
    City city = City.create(... );
}
于 2013-03-06T13:31:15.743 に答える
0

より良い方法:

 static public City create(string postnr, string navn, SqlConnection con)
 {
     DatabaseConnection.openConnection(con);
     using (var command = new SqlCommand("insert into [By] (Postnummer, Navn) values ('" + postnr + "', '" + navn + "'); select @@identity as 'identity';", con))
     {
         object ID = command.ExecuteScalar();

         City city = new City();
         city.id = Convert.ToInt32(ID);
         city.postnr = postnr;
         city.navn = navn;
         return city;
     }

     return null;
 }

Create メソッドは静的でなければならず、引数に都市を含める必要はありません。で呼び出す:

 if (city == null)
 {
      city = City.Create(.....);
 }
于 2013-03-06T13:35:49.620 に答える