C# CommandText属性未初始化

C# CommandText属性未初始化,c#,sql,C#,Sql,我似乎只有在我将工作代码更改为使用数据视图而不是文本框来显示一行数据之后才遇到这个问题 我有以下资料: static SqlConnection dbConnection = new SqlConnection (DBConnection.DBConnection.connectionString); SqlDataAdapter holdone = new SqlDataAdapter(getCommand, dbConne

我似乎只有在我将工作代码更改为使用数据视图而不是文本框来显示一行数据之后才遇到这个问题

我有以下资料:

static SqlConnection dbConnection = new SqlConnection
                       (DBConnection.DBConnection.connectionString);        
    SqlDataAdapter holdone = new SqlDataAdapter(getCommand, dbConnection);      

    DataSet holdall = new DataSet();
    DataSet updateall = new DataSet();
    DataTable invoiceTable = new DataTable();

    DataView invoiceView = new DataView();
它是由

public void GetOne(/* connectionString, string invref, string tableref*/)
    {

getCommand = "select *redacted* from " + tableref +  
                                      "where *redacted* = " + invref;

        using (SqlConnection dbConnection = new SqlConnection
                               (DBConnection.DBConnection.connectionString))
        {
                dbConnection.Open();

            holdone.Fill(holdall);

            invoiceTable = holdall.Tables[0];

            dbConnection.Close();


        }

        DataRowView rowView = invoiceView.AddNew();

            rowView["*redacted*"] = invoiceTable;

            rowView.EndEdit();
    }
错误报告将
holdone.fill(holdall)
作为违规行,但我不确定原因,因为我没有使用
SQLCommand
作为参数,而是使用
SQLDataAdapter
的参数


我正在努力找出哪里出了问题?

看起来您正在将
getCommand
传递给
SqlDataAdapter
构造函数,然后才将其分配给实际的SQL命令。首先初始化
getCommand
字符串,然后才构造
SqlDataAdapter
对象。

问题是您确实将
SqlDataAdapter
的select命令字符串设置为此行的
getCommand
的当前值:

SqlDataAdapter holdone = new SqlDataAdapter(getCommand, dbConnection); 
但是,由于字符串不是真正的指针,因此在单词后更改
getCommand
不会更改
SqlDataAdapter
的select命令

您需要做的是:

public void GetOne(/* connectionString, string invref, string tableref*/)
{

    getCommand = "select *redacted* from " + tableref + "where *redacted* = " + invref;
    using (SqlConnection dbConnection = new SqlConnection(DBConnection.DBConnection.connectionString))
    {
        dbConnection.Open();

        holdone.SelectCommand = new SqlCommand(getCommand, dbConnection);
        holdone.Fill(holdall);

        invoiceTable = holdall.Tables[0];
        //dbConnection.Close(); // This line is unnecessary, as the connection will be closed by `using`
    }

    DataRowView rowView = invoiceView.AddNew();
    rowView["*redacted*"] = invoiceTable;
    rowView.EndEdit();
}

您的
CommandText
是通过值传递给SqlDataAdapter的,而不是通过引用,因此在创建适配器后更改变量
getCommand
不会影响数据适配器。一个非常简单的演示是:

static void Main(string[] args)
{
    string r = "Test";
    using (var adapter = new SqlDataAdapter(r, new SqlConnection("")))
    {
        r = "Test2";
        Console.WriteLine(adapter.SelectCommand.CommandText);
    }

}
输出

试验

不是

测试2

您需要明确更改适配器的SelectCommand.CommandText:

holdone.SelectCommand.CommandText = getCommand;
因为像这样重用对象是没有帮助的,它甚至不能保存代码。NET使用连接池,因此使用多个SQL连接/适配器并不一定意味着要有多个到数据库的管道。您还应使用:


@Jonny ExecuteReader:CommandText属性尚未被删除initialized@Jonny啊。这是一个
invalidoOperationException
@AlexBell未初始化的命令文本与无效的命令语法之间存在差异。如果他只给命令分配了一些文本,他不会得到他得到的错误。@AlexBell原谅我,我的意思是该文本已从我的帖子中删除,而不是我实际使用的是
*
。很抱歉造成混淆。@AlexBell这里有一个误解-我试图指出您的评论对所提到的问题没有帮助:-)我需要使命令远离任何其他内容,因为我可能会重复使用适配器。此外,我刚刚尝试了这个,结果也是一样的。@Wolfish,然后你做错了。在
GetOne
方法中,您确实设置了
getCommand
,但没有将其分配给
holdone
SQL适配器的
CommandText
。请记住,您没有设置对
getCommand
的引用,而是在
SqlDataAdapter holdone=new SqlDataAdapter(getCommand,dbConnection)行中将内部命令文本设置为
getCommand
的当前值。更改
getCommand
不会更改
SqlDataAdapter
的命令文本!如果我使用这个,我能消除
holdone
声明中现有的重载吗?也就是说:
…ldone=newsqldataadapter(removethis)
?我真的认为您对
SqlDataAdapter
的用途有错误的理解。您永远不会创建一个将
DELETE
命令作为其select命令的
SqlDataAdapter
。。。基本上,数据适配器用于封装通常的选择/插入/更新/删除例程。您可以为每个操作分配一个
SqlCommand
。SELECT命令将在调用
Fill
时调用,其他命令将在调用
Update
方法时根据
DataTable
中行的行状态调用。您可能会问自己,在您的情况下,使用数据适配器是否是正确的解决方案。哦,我不是有意表示我正在以那种方式使用适配器。我只是想指定我所指的特定重载。所讨论的实际重载是
(getCommand,dbConnection)
。实际上,在
GetOne
方法之外声明
SqlDataAdapter
是没有意义的,因为它实际上应该是无状态的。您还可以在
填充
之前创建它,并在之后销毁它(使用
使用
)。如果是这种情况,我认为使用相同的适配器执行
更新()
?这是我在类的根目录下声明适配器的初衷。我很感激关于参数化查询的建议,我将对此进行研究。至于SelectCommand,上面@ThorstenDittmar的回答似乎有效。
string sql = "select *redacted* from " + tableref + " where *redacted* = @InvoiceParam";
using (var adapter = new SqlDataAdapter(sql, DBConnection.DBConnection.connectionString))
{
    adapter.SelectCommand.Parameters.AddWithValue("@InvoiceParam", invRef);
    adapter.Fill(holdall);
    invoiceTable = holdall.Tables[0];
}