I have two tables with foreign key, first one is:
tblFile : FileID, FileName...
And the second one is:
tblChild (in Datagridview) : ChildID, ChildName, ChildBirthDate, fkFileID.
When the Save button is clicked (in the Form), how can I update all the rows in second table if rows (Add or Edit or Delete)? (Form ex:
Make a new project, add a DataSet type of file and open it. Right click the surface, add a tableadapter
configure the connection string etc, choose Add from statements
Put a query that pulls by primary key
Add "ByFileId" to the names of the queries
Finish, and rename the generated datatable to remove the "tbl"
Repeat the process for the other table. You should see the relation appear too
That's your data access part sorted. You can look at the huge amount of well parameterized SQL code VS has written for you in the DataSetX.Designer.cs if you want to..
Open a new form in a designer mode, and show the data sources window (View menu, Other windows - hope you're using .net framework):
There are two Child nodes in the data sources because one is top level and one is related to the File; we'll use the File one because it'll demo loading and saving related data
Drag the following nodes onto the form:
I'm not trying to win any beauty contests here; just demoing a concept. Tarting it up can come later
That's it; everything needed to load update and save data has been done. You're right; i didn't write a single line of code
Let's put some dummy data into the db:
And, before we load the app, I'll just tweak a property on the tableadapter that will make it easier to load lots of data (because the only queries in the dataset at the moment can only load one record at once). Turn off ClearBeforeFill in both tableAdapters (in the tray under the form)
Run the app. I loaded all the data available in my db by entering 1 in the box, clicking Fill, changing to 2, Fill, then in the child box 1, fill, 2, fill, 3, fill - remember this is just a demo; all this can be done programmatically, and with different queries that select by name etc (tableadapters can have multiple queries)
You can click the nav at the top to switch the file between 1 and 2 and note the related records in the grid updates automatically:
you can edit anything you see and hit save
And it's in the DB and done..
If you'd added decords or deleted records, those changes would be saved too, by Update()
- it doesn't just call UPDATE queries, despite being called Update()
It's not magic, by the way; you can find all the code that did it in the .Designer files and the form codebehind.. it's just that it's all code that VS can do a better job of writing than we can so leave VS to do it, and just use the code it wrote for you
So how do we make these things useful? Querying by PK is all well and good but you don't ask a user to type PKs.. You can add more queries to your tableadapters that do other stuff:
Having added these queries to your adapters you could ask your user for a filename, then run a code like:
fileTableAdapter.FillByName(someDataset.File, filenametextbox.Text);
foreach(var f in someDataset.File){
childTableAdapter.FillByFileId(someDataset.Child, f.FileId);
}
That will pull a file(s) by name (the user can type % into the filename textboxfor a wildcard) and then, for each file record, pull all the related child records..
The tables in the stringly typed dataset are also nicer to query via LINQ:
someDataset.File.Where(f => f.FileId == "hello");