简体   繁体   English

在C#中将不接受空对象

[英]won't accept a null object in C#

When I run my code it tells me that the object of adr is null, and thats true, but why wont it work when it works in a duplicate of the same method, with the exeption of insert instead of select. 当我运行我的代码时,它告诉我adr的对象为null,这是对的,但是当它在相同方法的副本中工作时,为什么用插入而不是select代替,它为什么不起作用。

the code looks like this: 代码如下:

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;
    }
}

the call looks like this: 呼叫看起来像这样:

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
}

Well yes, look: 好吧,请看:

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

You're calling a method on a reference which is definitely null. 您正在引用绝对为空的引用上调用方法。 That's guaranteed to throw a NullReferenceException . 这样可以保证抛出NullReferenceException

You almost certainly want to make your create method static (and rename it to comply with normal .NET naming conventions), and call it as 几乎可以肯定,您希望将create方法设为静态(并将其重命名以符合常规的.NET命名约定),并将其称为

city = City.Create(...);

You'll also need to remove the city parameter from the method call, and instead create a new City object inside your method. 您还需要从方法调用中删除city参数,而是方法内部创建一个新的City对象。 For example: 例如:

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;
    }
}

Note how I've changed your code to use parameterized SQL too. 注意我如何更改您的代码以也使用参数化SQL。 You really, really, shouldn't put values directly into your SQL statement like that - it opens up your system to SQL injection attacks and makes various conversions messy. 确实,您确实不应该那样直接将值放入SQL语句中-它会使您的系统遭受SQL注入攻击 ,并使各种转换变得混乱。

Additionally, I would recommend creating a new SqlConnection (and closing it) for each database operation. 另外,我建议为每个数据库操作创建一个新的SqlConnection (并关闭它)。

Frankly it's a bit odd for doesExist to be an instance method, too... and again, for it to take a city parameter. 坦白说, doesExist成为实例方法也有点奇怪……再一次,它需要一个city参数。

I would suggest changing the design of this so that you have a CityRepository (or something similar) which knows the connection string, and exposes: 我建议更改其设计,以使您拥有一个知道连接字符串并公开的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)

The repository would know the relevant connection string, and would be responsible for all the database operations. 存储库将知道相关的连接字符串,并将负责所有数据库操作。 The City type would know nothing about databases. City类型对数据库一无所知。

You are trying to call a method on object class that has not been initialized/is null. 您试图在对象类上调用尚未初始化/为空的方法。

You need to make City.create a static member. 您需要使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;
    }
}

And use it like : 并像这样使用它:

if(city==null) 
{
    City city = City.create(... );
}

the better way : 更好的方法:

 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 method must be static, and no need to have city in argument. create方法必须是静态的,并且不需要在参数中包含city。 Call it with : 用:

 if (city == null)
 {
      city = City.Create(.....);
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM