The inital run of the application will not have any records, use the add button to add data.
Typically when a developer new to working with database data in a Windows Form application tend to add rows
directly to the DataGridView rather than set the DataGridView DataSource property
which means more code rather than setting the DataGridView DataSource property using a DataSet or DataTable.
When setting the DataSource property
for a DataGridView to a DataTable or DataSet then perform save operations all works as expected. This is not the case when working with Entity Framework Core 5 (EF Core 5).
Basic mistake where adding a new record (as shown in Form1
) will not display the new record in the DataGridView.
private async void OnShown(object sender, EventArgs e)
{
var list = await DataOperations.People();
dataGridView1.DataSource = list;
}
Next level is to use a BindingList<T>, in this case BindingList<Person
>.
The key is ToBindingList() extension method.
public static async Task<BindingList<Person>> PeopleLocal()
{
return await Task.Run(async () =>
{
await Context.Person.LoadAsync();
return Context.Person.Local.ToBindingList();
});
}
In Form2 data is load
private async void OnShown(object sender, EventArgs e)
{
BindingList<Person> peopleLocalList = await DataOperations.PeopleLocal();
dataGridView1.DataSource = peopleLocalList;
}
Now when adding a new Person record the record is displayed in the DataGridView.
Even better is to incorporate a BindingSource which provides navigation ability, useful methods and events.
private readonly BindingSource _bindingSource = new BindingSource();
private async void OnShown(object sender, EventArgs e)
{
BindingList<Person> peopleLocalList = await DataOperations.PeopleLocal();
_bindingSource.DataSource = peopleLocalList;
dataGridView1.DataSource = _bindingSource;
}
- Form1 just does not work
- Form2 we need to touch the DataGridView once loaded to get at loaded data
- Form3 Set the DataGridView.DataSource and no need to touch the DataGridView once loaded to access data.
- Check out 👉
ChangeTracker.DebugView.LongView
- Check out 👉
In DataOperations class, Show method provides access to the State of each record.
public static string Show()
{
StringBuilder builder = new ();
foreach (var person in Context.Person.Local)
{
if (Context.Entry(person).State != EntityState.Unchanged)
{
builder.AppendLine($"{person.Id} {person.FirstName} {person.LastName} {Context.Entry(person).State}");
}
}
return builder.ToString();
}
What can be learned is not to work directly with a DataGridView for displaying database data using EF Core 5 or higher.
Novice developers tend to want the easiest way to code a solution which is great while when they don�t understand and/or think ahead will a) write a good deal more code then required b) seek help and in many cases unwilling to accept, in this case using a BindingList with a BindingSource.
So looking at the big picture
past working with a DataGridView and EF Core is to think ahead for other coding task. Even better, take time when appropriate after reading documentation write unit test to validate that what you think the code should do actually does.
- Requires
- Visual Studio 2019 or higher
- SQL-Server Express edition or higher
- Run createPersonTable.sql script
- In Program.cs, set the startup form to Form1, run, try Form2, run the Form3 and run
- Microsoft TechNet Wiki
- Microsoft documentation
Added Form4
to respond to a form question.