NpgsqlCommandBuilder GetUpdateCommand抛出异常

时间:2012-09-05 14:33:38

标签: c# npgsql

我正在尝试使用NpgsqlCommandBuilder自动生成SQL命令以对数据集执行插入/更新/删除操作。数据集将绑定到数据网格(我真的不知道该怎么做)。所以我不会手动编辑数据集。当尝试自动生成sql命令时,它会在调用NpgsqlDataAdaptor.Update()时抛出异常

以下是db表的架构:

tblFee
{
    character(4) dest,
    character(4) id,
    character(2) indicator,
    double fee
}
the primary key is (dest, id, indicator)

这是我的代码:

string m_strConnection = "Server=192.168.253.20;Port=5432;User Id=alex;Password=asdf;Database=mydb;";
DataSet m_ds = new DataSet("EcnFeeData");
NpgsqlConnection m_conn = new NpgsqlConnection(m_strConnection);
NpgsqlDataAdapter m_dAdapter = new NpgsqlDataAdapter();
m_dAdapter.SelectCommand = new NpgsqlCommand("SELECT * FROM \"tblFee\"", m_conn);
NpgsqlCommandBuilder builder = new NpgsqlCommandBuilder(m_dAdapter);

m_conn.Open();

m_dAdapter.Fill(m_ds, "tblFee");

m_ds.Tables[0].Rows[0]["fee"] = 1;

builder.GetUpdateCommand();

m_dAdapter.Update(m_ds, "tblFee");

在最后一行执行时会抛出此异常:

A first chance exception of type 'System.InvalidOperationException' occurred in System.Data.dll

Additional information: Update requires a valid UpdateCommand when passed DataRow collection with modified rows.

尝试插入行时会发生同样的事情,只有异常消息不同:

Additional information: Update requires a valid InsertCommand when passed DataRow collection with new rows.

最后一个代码示例是尝试使用NpgsqlCommandBuilder,就像在.NET 4.0文档提供的示例中使用SqlCommandBuilder一样。 Npgsql文档没有提供这样做的示例。 NpgsqlCommandBuilder不支持此功能吗?我宁愿让NpgsqlCommandBuilder自动生成sql命令,但如果它不起作用,那么我将不得不手动创建它们。

按照Npgsql文档中的示例手动生成InsertCommand后,我能够让它工作,但我无法弄清楚如何为UpdateCommand执行此操作。这是我用来创建InsertCommand的代码:

m_dAdapter.InsertCommand = new NpgsqlCommand("insert into \"tblFee\" (dest, id, indicator, fee) values (:a, :b, :c, :d)", m_conn);
m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("a", DbType.AnsiStringFixedLength));
m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("b", DbType.AnsiStringFixedLength));
m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("c", DbType.AnsiStringFixedLength));
m_dAdapter.InsertCommand.Parameters.Add(new NpgsqlParameter("d", DbType.Double));

m_dAdapter.InsertCommand.Parameters[0].Direction = ParameterDirection.Input;
m_dAdapter.InsertCommand.Parameters[1].Direction = ParameterDirection.Input;
m_dAdapter.InsertCommand.Parameters[2].Direction = ParameterDirection.Input;
m_dAdapter.InsertCommand.Parameters[3].Direction = ParameterDirection.Input;

m_dAdapter.InsertCommand.Parameters[0].SourceColumn = "dest";
m_dAdapter.InsertCommand.Parameters[1].SourceColumn = "id";
m_dAdapter.InsertCommand.Parameters[2].SourceColumn = "indicator";
m_dAdapter.InsertCommand.Parameters[3].SourceColumn = "fee";
m_dAdapter.InsertCommand.Connection = m_conn;

这是我尝试执行UpdateCommand,但不起作用:

m_dAdapter.UpdateCommand = new NpgsqlCommand("update \"tblFee\" set dest = :a, id = :b, indicator = :c, fee = :d where dest = :e and id = :f and indicator = :g");
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("a", DbType.AnsiStringFixedLength));
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("b", DbType.AnsiStringFixedLength));
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("c", DbType.AnsiStringFixedLength));
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("d", DbType.Double)); 
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("e", DbType.AnsiStringFixedLength));
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("f", DbType.AnsiStringFixedLength));
m_dAdapter.UpdateCommand.Parameters.Add(new NpgsqlParameter("g", DbType.AnsiStringFixedLength));

m_dAdapter.UpdateCommand.Parameters[0].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[1].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[2].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[3].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[4].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[5].Direction = ParameterDirection.Input;
m_dAdapter.UpdateCommand.Parameters[6].Direction = ParameterDirection.Input;

m_dAdapter.UpdateCommand.Parameters[0].SourceColumn = "dest";
m_dAdapter.UpdateCommand.Parameters[1].SourceColumn = "id";
m_dAdapter.UpdateCommand.Parameters[2].SourceColumn = "indicator";
m_dAdapter.UpdateCommand.Parameters[3].SourceColumn = "fee";
m_dAdapter.UpdateCommand.Parameters[4].SourceColumn = "dest_orig";
m_dAdapter.UpdateCommand.Parameters[5].SourceColumn = "id_orig";
m_dAdapter.UpdateCommand.Parameters[6].SourceColumn = "indicator_orig";
m_dAdapter.UpdateCommand.Connection = m_conn;

非常感谢任何帮助。

亚历

2 个答案:

答案 0 :(得分:1)

您可以设置和操纵NpgsqlDataAdapter的{​​{1}},就像上面的UpdateCommand一样。

http://npgsql.projects.postgresql.org/docs/api/Npgsql.NpgsqlDataAdapterMembers.html处的文档外,它的工作方式与SqlDataAdapter类似,因此http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldataadapter.updatecommand.aspx的示例值得一看。

答案 1 :(得分:0)

要使用NpgsqlCommandBuilder,您需要:

m_dAdapter.InsertCommand = builder.GetInsertCommand(m_ds.Tables[0].Rows[0]);
m_dAdapter.UpdateCommand = builder.GetUpdateCommand(m_ds.Tables[0].Rows[0]);
m_dAdapter.DeleteCommand = builder.GetDeleteCommand(m_ds.Tables[0].Rows[0]);

尝试一下,让我们知道它是否适合您。事实上,如果你没有指出哪个适配器关联命令,我不知道为什么SqlCommandBuilder适合你。