shaunchristopher
asked on
DataGridView does not allow nulls.
Hi,
I'm using Visual Studio 2010 and the SQLite API. Here's the problem, I've got a generated data source for a SQLite Database table, I want to have an InsertCommand setup via the Query Builder which will insert only [Example] and [AssociativeID] into the SQL database, and not mess with the ID field, since the ID is a primary key and the SQLite database will automatically assign an autoincremented value for it.
I have a feeling it's impossible for me to update the DataGridView with the appropriate ID fields, since when the user adds a new row, it only inserts into the DataSet/DataAdapter, and the values aren't actually written into the SQL until I manually call Update on the TableAdapter.
However, the fact is, I just want to be able to allow the user to add a new row, but the DataError Method of the DataGridView is constantly throwing an error.
Here is the ExampleTable:
The database is very simple:
CREATE TABLE "ExampleTable" (
[ID] INTEGER PRIMARY KEY,
[Example] nvarchar NOT NULL,
[AssociativeID] INT NOT NULL
);
I've setup an XSD, and built an appropriate InsertCommand using the Query Builder for the table adapter.
The command looks like this:
INSERT INTO ExampleTable
(Example, AssociativeID)
VALUES (@Example, @AssociativeID)
************ Parameters Collection Editor ************
The "Parameters Collection Editor" shows two values:
@Example
@AssociativeID
I noticed that I could add a parameter called @ID,
and set a field called Direction to:
Input
Output
InputOutput
ReturnValue
************ XSD Designer ************
ExampleTable
ID DataColumn
AllowDBNull True/False // Doesn't make a difference
AutoIncrement // I don't want to programmatically set an ID for this field.
DefaultValue <DBNull>
NullValue (Throw exception) // Attempting to change this field results in "Property value is not valid."
ReadOnly False
************ DataGridView ************
Columns:
ID
ReadOnly = True // I don't want the user to mess with this field, since it is assigned automatically inside the SQL database.
Everything is setup correctly and refreshes properly, including changing row values.
Any attempt by the user to add a new row results in the following error:
System.Data.NoNullAllowedE xception: Column 'ID' does not allow nulls.
at System.Data.DataColumn.Che ckNullable (DataRow row)
at System.Data.DataTable.Rais eRowChangi ng(DataRow ChangeEven tArgs args, DataRow eRow, DataRowAction eAction, Boolean fireEvent)
at System.Data.DataTable.SetN ewRecordWo rker(DataR ow row, Int32 proposedRecord, DataRowAction action, Boolean isInMerge, Boolean suppressEnsurePropertyChan ged, Int32 position, Boolean fireEvent, Exception& deferredException)
at System.Data.DataTable.Inse rtRow(Data Row row, Int64 proposedID, Int32 pos, Boolean fireEvent)
at System.Data.DataView.Finis hAddNew(Bo olean success)
at System.Data.DataRowView.En dEdit()
at System.Windows.Forms.Curre ncyManager .EndCurren tEdit()
at System.Windows.Forms.DataG ridView.Da taGridView DataConnec tion.OnRow Validating (DataGridV iewCellCan celEventAr gs e)
I've tried handling this error manually by overriding the DataError method, it doesn't matter what I do, it will never save the changes.
This is a call I've used before, to get the new autoincremented ID from an SQL table after inserting a new row:
This works on this table without any problems.
So basically this is a two part problem.
Main problem is: How to allow the user to add new rows without having to add any values in the ID column, which is ReadOnly anyway.
Secondary problem: How to get the new ID from the database after doing an Update() and filling in the DataGridView.ID column.
I've been banging my head against the wall for almost five hours trying to figure out what I'm doing wrong. Please help!
I'm using Visual Studio 2010 and the SQLite API. Here's the problem, I've got a generated data source for a SQLite Database table, I want to have an InsertCommand setup via the Query Builder which will insert only [Example] and [AssociativeID] into the SQL database, and not mess with the ID field, since the ID is a primary key and the SQLite database will automatically assign an autoincremented value for it.
I have a feeling it's impossible for me to update the DataGridView with the appropriate ID fields, since when the user adds a new row, it only inserts into the DataSet/DataAdapter, and the values aren't actually written into the SQL until I manually call Update on the TableAdapter.
However, the fact is, I just want to be able to allow the user to add a new row, but the DataError Method of the DataGridView is constantly throwing an error.
Here is the ExampleTable:
The database is very simple:
CREATE TABLE "ExampleTable" (
[ID] INTEGER PRIMARY KEY,
[Example] nvarchar NOT NULL,
[AssociativeID] INT NOT NULL
);
I've setup an XSD, and built an appropriate InsertCommand using the Query Builder for the table adapter.
The command looks like this:
INSERT INTO ExampleTable
(Example, AssociativeID)
VALUES (@Example, @AssociativeID)
************ Parameters Collection Editor ************
The "Parameters Collection Editor" shows two values:
@Example
@AssociativeID
I noticed that I could add a parameter called @ID,
and set a field called Direction to:
Input
Output
InputOutput
ReturnValue
************ XSD Designer ************
ExampleTable
ID DataColumn
AllowDBNull True/False // Doesn't make a difference
AutoIncrement // I don't want to programmatically set an ID for this field.
DefaultValue <DBNull>
NullValue (Throw exception) // Attempting to change this field results in "Property value is not valid."
ReadOnly False
************ DataGridView ************
Columns:
ID
ReadOnly = True // I don't want the user to mess with this field, since it is assigned automatically inside the SQL database.
Everything is setup correctly and refreshes properly, including changing row values.
Any attempt by the user to add a new row results in the following error:
System.Data.NoNullAllowedE
at System.Data.DataColumn.Che
at System.Data.DataTable.Rais
at System.Data.DataTable.SetN
at System.Data.DataTable.Inse
at System.Data.DataView.Finis
at System.Data.DataRowView.En
at System.Windows.Forms.Curre
at System.Windows.Forms.DataG
I've tried handling this error manually by overriding the DataError method, it doesn't matter what I do, it will never save the changes.
This is a call I've used before, to get the new autoincremented ID from an SQL table after inserting a new row:
String insert_str = "INSERT INTO ExampleTable (Example, AssociativeID) VALUES(@Example, @AssociativeID); SELECT last_insert_rowid() AS NewID;";
sqlcmd.CommandText = insert_str.ToString();
sqlcmd.CommandType = CommandType.Text;
Object scalarresult = sqlcmd.ExecuteScalar();
Int64 newrow_id = Convert.ToInt64(scalarresult);
This works on this table without any problems.
So basically this is a two part problem.
Main problem is: How to allow the user to add new rows without having to add any values in the ID column, which is ReadOnly anyway.
Secondary problem: How to get the new ID from the database after doing an Update() and filling in the DataGridView.ID column.
I've been banging my head against the wall for almost five hours trying to figure out what I'm doing wrong. Please help!
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
@graye:
Whether or not the ID is included within the auto-generated SQL insert command has no effect. It happens when a new row is inserted within the DataGridView control validation code. However, as you said, the autonumber/autoincrement seems to be the root of the problem, I will post my resulting code as below, for anyone who finds it useful:
Under the primary key:
Set AutoIncrement = true
AutoIncrementSeed = -1
AutoIncrementStep = -1
In this way, the datagridview value doesn't actually map to any real values nor conflict with any existing values in that DataGridView control column. After doing an Update and Fill again, the DataGridView will repopulate that row with the true SQL table generated ID.
@jpaulino: Thanks for the code sample, but it doesn't really have any relation to my problem.
Whether or not the ID is included within the auto-generated SQL insert command has no effect. It happens when a new row is inserted within the DataGridView control validation code. However, as you said, the autonumber/autoincrement seems to be the root of the problem, I will post my resulting code as below, for anyone who finds it useful:
Under the primary key:
Set AutoIncrement = true
AutoIncrementSeed = -1
AutoIncrementStep = -1
In this way, the datagridview value doesn't actually map to any real values nor conflict with any existing values in that DataGridView control column. After doing an Update and Fill again, the DataGridView will repopulate that row with the true SQL table generated ID.
@jpaulino: Thanks for the code sample, but it doesn't really have any relation to my problem.
https://www.experts-exchange.com/questions/23292122/Write-data-from-DataTable-to-MS-Access-database.html