0

当我运行我的代码时,它告诉我 adr 的对象为空,这是真的,但是为什么当它在相同方法的副本中工作时它不能工作,除了插入而不是选择。

代码如下所示:

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(...);
}

您正在调用绝对为空的引用的方法。这保证会抛出一个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

您正在尝试调用尚未初始化/为空的对象类的方法。

您需要创建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;
 }

创建方法必须是静态的,并且不需要在参数中包含城市。调用它:

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