C# Help filling DataTables with foreign keys - c#

In Visual Studio Designer, I have created a DataSet that has 2 DataTables; EmployeeDT and PayrollSheetDT which pull data from SQL Server via SELECT statements. The two DataTables have a relation via the SSN column.
Relevant SQL Server database structure:
Table: Employee, columns: SSN (primary key), Driver
Table: PayrollSheet, columns: SSN (foreign key), PSDate
In my PayrollSheet form, I have multiple combo boxes where I have bound DataSource, DisplayMember and ValueMember of the EmployeeDT DataTable. When I start the program, I am successful in clicking the down arrow in the "Driver" combobox, choosing a drivers name, and having the other comboboxes display information from that Driver / SQL record - as they are bound to the same DataSource.
I also have a listbox next to the comboboxes, with the goal of displaying the PSDate for whatever SSN is selected in the comboboxes.
The listbox is my issue. I need to be able to change the value in any combobox, and have the PSDate displayed in the listbox. I don't know if this can be done, as the PayrollSheetDT DataTable executes a static SQL query, but what I'm wanting would be the equivalent of adding a WHERE SSN = <selected ssn in other datatable>
I don't have a good understanding of how to do this, but if I try to fill the TableAdapter, I get the following error:
One or more rows contain values violating non-null, unique, or foreign-key constraints.
Thanks for your help

These things are VERY finickly.
That error could mean a few things. Try to (temporarily) delete the PayrollSheet table and only populate the Employee table.
Make sure your column names match the sql query, like the short words/phrases for the column names are exact matches. EmployeeLastName is not the same as EmployeeLName.
Make sure there is not an "extra" PayrollSheet row that doesn't have a parent row (back to Employee), aka, an orphan row in PayrollSheet.
Here is a generic helper. Try to populate a DataSet object (just "DataSet", not a strongly typed one)...and then do a ds.WriteXml(#"C:\myds.xml") and then go through that xml and make sure the column names match.
Also..check datatypes. Check that a column (in the ds definition) isn't marked as "not null" and then the query returns a null value for some row. It's some kind of tick tack issue, I'm pretty sure.
99x out of 100x, when I had this issue, it was something tiny tiny that screwed me.

Related

Datasource gridview c#

i'm new on .net, and i'm trying to make a gridview table that take data from a database (i bind data with <asp:sqldatasource selectcommand> tag) and for a specific integer value from this table column i want to display in gridview a string that is in another table and is specific for the integer.
So 2 tables, 1 is inserted in gridview, another has static number of columns, table "a" has integers and other columns, tabel "b" has same integers but different strings on other columns for them. In gridview i want to show other columns from table "a" and 1 column from table "b".
I can display the first table but i don't have ideas to link 2 tables.
I can't make changes in databes.
Thank you!
Table a Table b
column1 column2 column3 column4 column5
data1 data2 integer integer string
Output
Gridview
column1 column2 column5
To display the other data, then simply use a left join in your sql.
So, say we have this to load up the data grid:
if (IsPostBack == false)
{
GridView1.DataSource = Myrst("Select FirstName, LastName, Hotel_ID FROM tblBooked");
GridView1.DataBind();
}
We thus get this result:
But, that hotel_id is rather ugly, so we want to pull that data from tblHotels
So, you simply left join in the other table. You can write out the sql, or say lets create a view like this:
Now, our simple code can say go like this:
GridView1.DataSource = Myrst("SELECT * from vBookedHotels");
GridView1.DataBind();
And we get this result:
So the "general" approach here is to write some sql and use a left join. You can thus quite much pull in any "id" value and translate it to the other table. So friendly text names or descriptions can thus be pulled from the other table.
I recommend using SQL for this, since then your two lines of code to load up the gridview can be done as per above. And it often possible that you need to do this in several places in your application - so a handy view to query against makes is rather easy.
in above, I use a custom routine called MyRst(), and all it does is create the sqlcommand object, get the connection and returns a data table (i was tired of writing the same code over and over (eg: create connection, create data adaptor etc - so I just put that code in a simple routine, and now I can just type in some sql and quite much assign it to a gridview, or even a listview, or even dropdown boxes with the two lines of code as per above.
So, the general approach here is to use SQL to get/grab/pull and translate some "ID" in a column to some nice user friendly description or text columns in the 2nd table as you outlined.

SQLiteAsyncConnection inserting multiple row in order?

I used SQLite before, and adding multiple rows using Insert in a for loop was slow. The solution was using a transaction.
Now that I am using SQLiteAsyncConnection in SQLite.Net (for ORM), I also tried to use a transaction. It works but with only one problem. The insert order is not the order of the data.
Database.RunInTransactionAsync(
(SQLiteConnection conn) => {
foreach (var row in rows)
{
conn.InsertOrReplace(row);
}
conn.Commit();
}
);
If rows contained [1,2,3,4,5,6], the rows in the database was something like [3,1,2,6,4,5]. How can I keep the original order?
Note that I only mean newly inserted rows. Even thought the code is replacing existing rows, when testing there were no existing rows in the database to be replaced.
PS: The row has ID field which is the [PrimaryKey], but in the rows the rows are not sorted by ID. It seems that in the database the rows are sorted by ID. I do not want it to be sorted by ID but the original order to be maintained.
PS 2: I need to know the ID of the last-inserted row. When viewing the database using a GUI tool like DB Browser for SQLite or getting the last item by LIMIT 1, it seems the SQLite had automatically sorted the rows by ID. I did some Google search and it said by the rules of SQL, when there is no ORDER BY, the order of the returned rows are not guaranteed to be the physical order, anyway. Should I create another field and set it as the primary, auto-increasing field?
Currently, ID is guaranteed to be unique per row, but 'ID' is part of the data itself, not a field specially added for the use with the database.
SQL tables are logically unordered, so if you want a certain order, you always have to use ORDER BY in your queries.
If your data does not contain any values (e.g., timestamp) that corresponds to the insertion order, then you have to use the rowid, i.e., add a column declared as INTEGER PRIMARY KEY.

Reading yes/no fields from Access DB yields DBnull

I am adding a column/field to an existing Access database as a yes/no field so that there is a checkbox displayed for user input/editing from within Access tools as well as external programmatically.
I create the column in the table with this SQL statement
"ALTER TABLE tablename ADD COLUMN UpdateLocked YESNO".
(I learned from MS documents that I can't enter a DEFAULT portion to this statement!)
After the creation, and anytime later on startup, I create an adapter by:
OleDbDataAdapter adapter = new OleDbDataAdapter();
adapter.SelectCommand = "SELECT * FROM tablename";
DataTable[] dtSchema = adapter.FillSchema(DBname, SchemaType.Source);
adapter.Fill(DataSet name); //Dataset used in DataGridView object
The effect I see is:
The added column schema is correctly shown as Boolean in the VS 2012 debugger.
The column is shown as a '{}' uninitialized value in the "item array" instead of true/false as other already existing YES/NO columns do.
Manually entered records in the Access DB with a true or false condition don't display in the DataGridView that uses the DataSet. No matter the value.
If I use the DataGridView to enter a true/false in various records of the view that uses this DataSet, the column/field schema is now "corrected" and a true/false is correctly displayed in the "item array" debugger display instead of the {} uninitialized value.
I want it to allow correctly reading the YESNO field data, but changing the syntax of the creation SQL or the SELECT statement have no effect.
Previously created YESNO columns display correctly, is there a different way to do the ALTER statement creating the column that I can use?
The failure of the ALTER OleDb command attempting to set default is one item that can be fixed with an Update command to set all of the new records field values just after adding. The primary concern I have is not being able to read the YESNO stored values at all in my DataGridView column checkboxes. The values aren't initialized during the adapter.Fill(). (Displays a {} value in Debugger.)
I found that the only way I could get the YESNO field to init properly was to initialize each Boolean to false after I created the field programmatically with a subsequent "UPDATE tablename SET fieldname = false". Thank you for looking at my question. After setting the default this way, it seemed to work fine. This really seemed unnecessary, but it worked.

c# - Failed to enable constraints when filling datatable [duplicate]

I make an outer join and executed successfully in the informix database but I get the following exception in my code:
DataTable dt = TeachingLoadDAL.GetCoursesWithEvalState(i, bat);
Failed to enable constraints. One or more rows contain values
violating non-null, unique, or foreign-key constraints.
I know the problem, but I don't know how to fix it.
The second table I make the outer join on contains a composite primary key which are null in the previous outer join query.
EDIT:
SELECT UNIQUE a.crs_e, a.crs_e || '/ ' || a.crst crs_name, b.period,
b.crscls, c.crsday, c.from_lect, c.to_lect,
c.to_lect - c.from_lect + 1 Subtraction, c.lect_kind, e.eval, e.batch_no,
e.crsnum, e.lect_code, e.prof_course
FROM rlm1course a, rfc14crsgrp b, ckj1table c, mnltablelectev d,
OUTER(cc1assiscrseval e)
WHERE a.crsnum = b.crsnum
AND b.crsnum = c.crsnum
AND b.crscls = c.crscls
AND b.batch_no = c.batch_no
AND c.serial_key = d.serial_key
AND c.crsnum = e.crsnum
AND c.batch_no = e.batch_no
AND d.lect_code= e.lect_code
AND d.lect_code = ....
AND b.batch_no = ....
The problem happens with the table cc1assiscrseval. The primary key is (batch_no, crsnum, lect_code).
How to fix this problem?
EDIT:
According to #PaulStock advice:
I do what he said, and i get:
? dt.GetErrors()[0] {System.Data.DataRow} HasErrors: true ItemArray:
{object[10]} RowError: "Column 'eval' does not allow DBNull.Value."
So I solve my problem by replacing e.eval to ,NVL (e.eval,'') eval.and this solves my problem.
Thanks a lot.
This problem is usually caused by one of the following
null values being returned for columns not set to AllowDBNull
duplicate rows being returned with the same primary key.
a mismatch in column definition (e.g. size of char fields) between the database and the dataset
Try running your query natively and look at the results, if the resultset is not too large. If you've eliminated null values, then my guess is that the primary key columns is being duplicated.
Or, to see the exact error, you can manually add a Try/Catch block to the generated code like so and then breaking when the exception is raised:
Then within the command window, call GetErrors method on the table getting the error.
For C#, the command would be ? dataTable.GetErrors()
For VB, the command is ? dataTable.GetErrors
This will show you all datarows which have an error. You can get then look at the RowError for each of these, which should tell you the column that's invalid along with the problem. So, to see the error of the first datarow in error the command is:
? dataTable.GetErrors(0).RowError
or in C# it would be ? dataTable.GetErrors()[0].RowError
You can disable the constraints on the dataset. It will allow you to identify bad data and help resolve the issue.
e.g.
dataset.TableA.Clear();
dataset.EnforceConstraints = false;
dataAdapter1.daTableA.Fill(dataset, TableA");
The fill method might be slightly different for you.
This will find all rows in the table that have errors, print out the row's primary key and the error that occurred on that row...
This is in C#, but converting it to VB should not be hard.
foreach (DataRow dr in dataTable)
{
if (dr.HasErrors)
{
Debug.Write("Row ");
foreach (DataColumn dc in dataTable.PKColumns)
Debug.Write(dc.ColumnName + ": '" + dr.ItemArray[dc.Ordinal] + "', ");
Debug.WriteLine(" has error: " + dr.RowError);
}
}
Oops - sorry PKColumns is something I added when I extended DataTable that tells me all the columns that make up the primary key of the DataTable. If you know the Primary Key columns in your datatable you can loop through them here. In my case, since all my datatables know their PK cols I can write debug for these errors automatically for all tables.
The output looks like this:
Row FIRST_NAME: 'HOMER', LAST_NAME: 'SIMPSON', MIDDLE_NAME: 'J', has error: Column 'HAIR_COLOR' does not allow DBNull.Value.
If you're confused about the PKColumns section above - this prints out column names and values, and is not necessary, but adds helpful troubleshooting info for identifying which column values may be causing the issue. Removing this section and keeping the rest will still print the SQLite error being generated, which will note the column that has the problem.
Ensure the fields named in the table adapter query match those in the query you have defined. The DAL does not seem to like mismatches. This will typically happen to your sprocs and queries after you add a new field to a table.
If you have changed the length of a varchar field in the database and the XML contained in the XSS file has not picked it up, find the field name and attribute definition in the XML and change it manually.
Remove primary keys from select lists in table adapters if they are not related to the data being returned.
Run your query in SQL Management Studio and ensure there are not duplicate records being returned. Duplicate records can generate duplicate primary keys which will cause this error.
SQL unions can spell trouble. I modified one table adapter by adding a ‘please select an employee’ record preceding the others. For the other fields I provided dummy data including, for example, strings of length one. The DAL inferred the schema from that initial record. Records following with strings of length 12 failed.
This worked for me, source: here
I had this error and it wasn't related with the DB constrains (at least in my case). I have an .xsd file with a GetRecord query that returns a group of records. One of the columns of that table was "nvarchar(512)" and in the middle of the project I needed to changed it to "nvarchar(MAX)".
Everything worked fine until the user entered more than 512 on that field and we begin to get the famous error message "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."
Solution: Check all the MaxLength property of the columns in your DataTable.
The column that I changed from "nvarchar(512)" to "nvarchar(MAX)" still had the 512 value on the MaxLength property so I changed to "-1" and it works!!.
The problem is with the Data Access designer. In Visual Studio, When we pull a View from "Server Explorer" to the Designer window, it is adding either a Primary key on a column randomly or marking something to a NOT NULL though it is actually set to null. Though the actual View creation in the SQL db server, doesn't have any primary key defined or the NOT NULL defined, the VS designer is adding this Key/constraint.
You can see this in the designer - it is shown with a key icon on left of the column name.
Solution: Right click on the key icon and select 'Delete Key'. This should solve the problem. You can also right click on a column and select "Properties" to see the list of properties of a column in the VS Data access designer and change the values appropriately.
This error was also showing in my project. I tried all the proposed solutions posted here, but no luck at all because the problem had nothing to do with fields size, table key fields definition, constraints or the EnforceConstraints dataset variable.
In my case I also have a .xsd object which I put there during the project design time (the Data Access Layer). As you drag your database table objects into the Dataset visual item, it reads each table definition from the underlying database and copies the constraints into the Dataset object exactly as you defined them when you created the tables in your database (SQL Server 2008 R2 in my case). This means that every table column created with the constraint of "not null" or "foreign key" must also be present in the result of your SQL statement or stored procedure.
After I included all the key columns and the columns defined as "not null" into my queries the problem disappeared completely.
Mine started working when I set AllowDBNull to True on a date field on a data table in the xsd file.
It sounds like possibly one or more of the columns being selected with:
e.eval, e.batch_no, e.crsnum, e.lect_code, e.prof_course
has AllowDBNull set to False in your Dataset defintion.
It is not clear why running a SELECT statement should involve enabling constraints. I don't know C# or related technologies, but I do know Informix database. There is something odd going on with the system if your querying code is enabling (and presumably also disabling) constraints.
You should also avoid the old-fashioned, non-standard Informix OUTER join notation. Unless you are using an impossibly old version of Informix, you should be using the SQL-92 style of joins.
Your question seems to mention two outer joins, but you only show one in the example query. That, too, is a bit puzzling.
The joining conditions between 'e' and the rest of the tables is:
AND c.crsnum = e.crsnum
AND c.batch_no = e.batch_no
AND d.lect_code= e.lect_code
This is an unusual combination. Since we do not have the relevant subset of the schema with the relevant referential integrity constraints, it is hard to know whether this is correct or not, but it is a little unusual to join between 3 tables like that.
None of this is a definitive answer to you problem; however, it may provide some guidance.
Thank you for all the input made so far. I just wanna add on that while one may have successfully normalized DB, updated any schema changes to their application (e.g. to dataset) or so, there is also another cause: sql CARTESIAN product (when joining tables in queries).
The existence of a cartesian query result will cause duplicate records in the primary (or key first) table of two or more tables being joined.
Even if you specify a "Where" clause in the SQL, a Cartesian may still occur if JOIN with secondary table for example contains the unequal join (useful when to get data from 2 or more UNrelated tables):
FROM tbFirst INNER JOIN
tbSystem ON tbFirst.reference_str <> tbSystem.systemKey_str
Solution for this:
tables should be related.
Thanks. chagbert
I solved the same problem by changing this from false to true. in the end I went into the database and changed my bit field to allow null, and then refreshed my xsd, and refreshed my wsdl and reference.cs and now all is well.
this.columnAttachPDFToEmailFlag.AllowDBNull = true;
Short and easy Soloution:
Go to MSSQL Studio Sever ;
Run the query of the cause of this error : in my case i see that id value was null because i forget to set Identity specification increment by 1.
So entered 1 for the id field as its is autoincremane and modify dont allow NULLS in desing view
That was the error that caused my bindingsource and tabel adapter throwin error at this code:
this.exchangeCheckoutReportTableAdapter.Fill(this.sbmsDataSet.ExchangeCheckouReportTable);
DirectCast(dt.Rows(0),DataRow).RowError
This directly gives the error
If you are using visual studio dataset designer to get the data table, and it is throwing an error 'Failed to Enable constraints'. I've faced the same problem, try to preview the data from the dataset designer itself and match it with table inside your database.
The best way to solve this issue is to delete the table adapter and create a new one instead.
* Secondary way : *
If you don't need [id] to be as Primary key,
Remove its primary key attribute:
on your DataSet > TableAdapter > right click on [id] column > select Delete key ...
Problem will be fixed.
I also had this issue and it was resolved after modifying the *.xsd to reflect the revised size of the column changed in the underlying SQL server.
To fix this error, i took off the troubling table adapter from the Dataset designer, and saved the dataset, and then dragged a fresh copy of the table adapter from the server explorer and that fixed it
I resolved this problem by opening the .xsd file with an XML reader and deleting a constraint placed on one of my views. For whatever reason when I added the view to the data it added a primary key constraint to one of the columns when there shouldn't have been one.
The other way is to open the .xsd file normally, look at the table/view causing the issue and delete any keys (right click column, select delete key) that should not be there.
Just want to add another possible reason for the exception to those listed above (especially for people who like to define dataset schema manually):
when in your dataset you have two tables and there is a relationship (DataSet.Reletions.Add()) defined from first table's field (chfield) to the second table's field (pfield), there is like an implicit constraint is added to that field to be unique even though it may be not specified as such explicitly in your definition neither as unique nor as a primary key.
As a consequence, should you have rows with repetitive values in that parent field (pfield) you'll get this exception too.
In my case this error was provoked by a size of a string column. What was weird was when I executed the exact same query in different tool, repeated values nor null values weren't there.
Then I discovered that the size of a string column size was 50 so when I called the fill method the value was chopped, throwing this exception.
I click on the column and set in the properties the size to 200 and the error was gone.
Hope this help
I solved this problem by doing the "subselect" like it:
string newQuery = "select * from (" + query + ") as temp";
When do it on mysql, all collunms properties (unique, non-null ...) will be cleared.
using (var tbl = new DataTable())
using (var rdr = cmd.ExecuteReader())
{
tbl.BeginLoadData();
try
{
tbl.Load(rdr);
}
catch (ConstraintException ex)
{
rdr.Close();
tbl.Clear();
// clear constraints, source of exceptions
// note: column schema already loaded!
tbl.Constraints.Clear();
tbl.Load(cmd.ExecuteReader());
}
finally
{
tbl.EndLoadData();
}
}
I received the same error type and in my case it solved it by removing the select fields and replacing them with a *. No idea why it was happening. The query had no typos or anything fancy.
Not the best solution but nothing else worked and I was getting exhausted.
In my search for a clear answer I found this on this:
https://www.codeproject.com/questions/45516/failed-to-enable-constraints-one-or-more-rows-cont
Solution 8
This error was also showing in my project, using Visual Studio 2010. I tried other solutions posted in other blogs, but no luck at all because the problem had nothing to do with fields size, table key fields definition, constraints or the EnforceConstraints dataset variable.
In my case I have a .xsd object which I put there during the project design time (in the Data Access Layer). As you drag your database table objects into the Dataset visual item, it reads each table definition from the underlying database and copies the constraints into the Dataset object exactly as you defined them when you created the tables in your database (SQL Server 2008 R2 in my case). This means that every table column created with the constraint of "not null" or "foreign key" must also be present in the result of your SQL statement or stored procedure.
After I included all the constrained columns (not null, primary key, foreign key, etc) into my queries the problem disappeared completely.
Perhaps you don't need all the table columns to be present in the query/stored procedure result, but because the constraints are still applied the error is shown if some constrained column does not appear in the result.
Hope this helps someone else.
If you have failing DataSet (not DataTable):
if (dataSet.HasErrors)
foreach (DataTable table in dataSet.Tables)
if (table.HasErrors)
foreach (var row in table.GetErrors())
Debug.Write($"Error in DataTable {table.TableName}: {row.RowError}")
if _sample_DataSet was the name of dataset that encounter error while filling, you can put the fill dataset inside a Try Catch and then put following code in catch{} block then you are able to exactly find the erroneous column.
foreach (DataTable _dtable in _sample_DataSet.DataSet.Tables)
{
foreach (DataRow dr in _dtable.Rows)
{
if (dr.HasErrors)
{
if (dr.HasErrors)
{
Debug.Write("Row error="+dr.RowError);
}
}
}

How to refresh datagridview binding in vb.net or C#?

I created two tables(FIRSTtable and SECONDtable) in the mysql database and two tables that are related.
The FIRST table, has a columns (product_id (pK), product_name).
The SECOND table has an columns (machine_id, production_date, product_id (fK),
product_quantity, operator_id).
Relations between the two tables using the product_id column with UpdateCascade and DeleteCascade. Both relationships are functioning normally when I try with the sql script. Suppose I delete all product_id in the FIRST table, all existing data in the SECOND table will be deleted.
Both of these tables displayed in datagridview. When I delete all the data in the FIRST table, the all rows in datagridview FIRST table will be deleted, also the data in mysql the FIRST table will be deleted.
I try to open the mysql database, the data are in SECOND Table also deleted, the problem why the view that in the second datagridview, can not be deleted, still keep the previous data? How to refresh datagridview binding in vb.net or C#? Thanks.
With Me.SECOND_DataGridView
.Datasource = Nothing ' tried this, but failed.
.DataSource = MyDataset.Tables("SECOND_table")
End With
I believe what you are running into is the fact the the MySQL Engine is actually performing the cascading deletes for you.
When you query the MySQL Data into a localized C# "DataTable" (Table within a DataSet), that data is now in memory and not directly linked to that on the disk. When you go to delete the rows in the "memory" version of the first data table, its causing the deletions to occur at the SERVER for the second level table and NOT directly updating you in-memory version of data table two.
That being said, you will probably have to do one of two things... Requery the entire dataset (tables one and two) to get a full refresh of what is STILL in the actual database... OR... As you are calling the delete from table one of the dataset, you'll have to perform the delete handling in the local datatable TWO as well to keep it in synch.

Categories