Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非静态字段、方法或属性需要对象引用';客户添加新客户(参考客户)_C#_Sql - Fatal编程技术网

C# 非静态字段、方法或属性需要对象引用';客户添加新客户(参考客户)

C# 非静态字段、方法或属性需要对象引用';客户添加新客户(参考客户),c#,sql,C#,Sql,对于此代码行 bool rowsAffected = CustDAL.AddNewCust(ref newCustomer); 我得到一个错误: 非静态字段、方法或属性需要对象引用 'CustDAL.AddNewCust(参考客户) 奶油冻里的代码看起来像 public bool AddNewCust(ref Models.Customer newCustomer) { SqlCommand command = new SqlCommand {

对于此代码行

bool rowsAffected = CustDAL.AddNewCust(ref newCustomer);
我得到一个错误:

非静态字段、方法或属性需要对象引用 'CustDAL.AddNewCust(参考客户)

奶油冻里的代码看起来像

 public bool AddNewCust(ref Models.Customer newCustomer)
    {
        SqlCommand command = new SqlCommand
        {
            CommandText = string.Format("INSERT INTO CUSTOMER VALUES('{0}', '{1}', '{2}', '{3}','{4}')", newCustomer.Title, newCustomer.Forename, newCustomer.Surname, newCustomer.Address, newCustomer.PhoneNumber)
        };

        return ExecuteNonQuery(command);
    }

这段代码在几个不同的层面上都很糟糕

首先,它为SQL注入攻击打开了大门。
如果有人将客户的标题设置为,比如,
Title');升降台客户--,想知道接下来会发生什么吗?
决不要将字符串与用户输入连接起来以创建SQL语句。相反,使用参数化查询将用户输入安全地发送到数据库。 正确的insert语句如下所示:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
第二个,如果从Customer表中添加或删除列,代码将中断。在编写insert语句时,始终指定列列表。
为中间名向Customer表中添加新列。如果这样做,当前语句将中断,因为列数将停止与值数匹配

第三个,如果newCustomer的任何字符串属性包含“char”,您将得到一个异常-因为您的SQL将变成如下所示:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
第四个,您正在传递一个SqlCommand实例,而不处理它。 虽然不处理
SqlCommand
并不可怕,因为它不包含任何非托管资源,但这是一个实现细节。事实上,它正在实现
IDisposable
接口,因此应该进行处理。你可以在网上读到更多关于这方面的内容。实现
IDisposable
接口的实例的最佳实践用法是作为
内的局部变量使用
station-

using(var cmd = new SqlCommand(sql, con))
{
    //... do command stuff here
}
Fifth
DbCommand.ExecuteNonQuery
返回一个int值作为原因。
ExecuteNonQuery
的返回值表示受SQL语句影响的行数。
如果您使用的查询试图插入多条记录或更新多条记录,您可能需要知道这些记录如何实际插入或更新。
返回bool会对调用代码隐藏该数据

Sixth,通过引用传递
newCustomer
参数没有意义,除非该方法初始化
Models.Customer的新实例并将其分配给
newCustomer
引用

因此,
AddNewCust
方法的更好实现可能更像这样:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
话虽如此,当前出现异常的原因是您试图将实例成员当作静态成员来执行—我猜
CustDAL
是类的名称,而不是该类实例的引用名称。
有关更多信息,请阅读 您应该首先创建
CustDAL
类的实例,然后才能访问它的非静态成员。由于DAL类可能会在整个应用程序中使用,因此在调用类中可能会有一个包含该引用的字段:

private CustDAL _custDal;

// in the constructor:

_custDal = new CustDAL();

// when you want to add a new customer:

var rowsAffected = _custDal.AddNewCust(newCustomer);

这段代码在几个不同的层面上都很糟糕

首先,它为SQL注入攻击打开了大门。
如果有人将客户的标题设置为,比如,
Title');升降台客户--,想知道接下来会发生什么吗?
决不要将字符串与用户输入连接起来以创建SQL语句。相反,使用参数化查询将用户输入安全地发送到数据库。 正确的insert语句如下所示:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
第二个,如果从Customer表中添加或删除列,代码将中断。在编写insert语句时,始终指定列列表。
为中间名向Customer表中添加新列。如果这样做,当前语句将中断,因为列数将停止与值数匹配

第三个,如果newCustomer的任何字符串属性包含“char”,您将得到一个异常-因为您的SQL将变成如下所示:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
第四个,您正在传递一个SqlCommand实例,而不处理它。 虽然不处理
SqlCommand
并不可怕,因为它不包含任何非托管资源,但这是一个实现细节。事实上,它正在实现
IDisposable
接口,因此应该进行处理。你可以在网上读到更多关于这方面的内容。实现
IDisposable
接口的实例的最佳实践用法是作为
内的局部变量使用
station-

using(var cmd = new SqlCommand(sql, con))
{
    //... do command stuff here
}
Fifth
DbCommand.ExecuteNonQuery
返回一个int值作为原因。
ExecuteNonQuery
的返回值表示受SQL语句影响的行数。
如果您使用的查询试图插入多条记录或更新多条记录,您可能需要知道这些记录如何实际插入或更新。
返回bool会对调用代码隐藏该数据

Sixth,通过引用传递
newCustomer
参数没有意义,除非该方法初始化
Models.Customer的新实例并将其分配给
newCustomer
引用

因此,
AddNewCust
方法的更好实现可能更像这样:

INSERT INTO TableName(Column1, Column2....Columnn) VALUES(@Param1, @Param2...@Paramn)
INSERT INTO CUSTOMER VALUES('My title isn't that smart', 'My forename',...
public int AddNewCust(ref Models.Customer newCustomer)
{
    var sql = "INSERT INTO CUSTOMER (Title, Forename, Surname, Address, PhoneNumber) VALUES (@Title, @Forename, @Surname, @Address, @PhoneNumber)";
    using(var command = new SqlCommand(sql))
    {
        command.Parameters.Add("@Title", SqlDbType.VarChar).Value = newCustomer.Title;
        command.Parameters.Add("@Forename", SqlDbType.VarChar).Value = newCustomer.Forename;
        command.Parameters.Add("@Surname", SqlDbType.VarChar).Value = newCustomer.Surname;
        //  fill in the rest of the parameters here...
        return ExecuteNonQuery(command); // change this method to return int...
    };
}
话虽如此,当前出现异常的原因是您试图将实例成员当作静态成员来执行—我猜
CustDAL
是类的名称,而不是该类实例的引用名称。
有关更多信息,请阅读 您应该首先创建
CustDAL
类的实例,并且只创建