Goal
I intend to update records from WPF application to MySQL.
The is the loaded data:
User is able to edit the data:
On button click, the data should update:
It detects the changes from the UI and shows updated records.
Problem
When looking in my database, I see the column Name
has changed but PositionId
remained the same:
Why is PositionId
not updating? And how can I update it?
Code
Models
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public Position Position { get; set; }
}
public class Position
{
public int PositionId { get; set; }
public string PositionTitle { get; set; }
public override bool Equals(object obj)
{
return obj is Position p && PositionId == p.PositionId;
}
public override int GetHashCode() => PositionId.GetHashCode();
}
View Model
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<Person> people;
public ObservableCollection<Person> People
{
get { return people; }
set
{
people = value;
OnPropertyChanged();
}
}
private ObservableCollection<Position> _positions;
public ObservableCollection<Position> Positions
{
get { return _positions; }
set
{
_positions = value;
OnPropertyChanged();
}
}
private static string connString = "..Connection String Goes here";
private List<Person> LoadPersonData()
{
string query = "SELECT PersonId, Name, b.PositionId, b.PositionTitle FROM Person a JOIN Position b ON a.PositionId = b.PositionId";
using (MySqlConnection conn = new MySqlConnection(connString))
{
var details = conn.Query<Person, Position, Person>(query, (person, position) =>
{
person.Position = position;
return person;
}, splitOn: "PositionId").ToList();
return details;
}
}
private List<Position> LoadPositionsData()
{
string query = "SELECT PositionId, PositionTitle FROM Position";
using (MySqlConnection conn = new MySqlConnection(connString))
{
var details = conn.Query<Position>(query).ToList();
return details;
}
}
public MainViewModel()
{
People = new ObservableCollection<Person>();
Positions = new ObservableCollection<Position>();
// Add each record to property named People
LoadPersonData().ForEach(record => People.Add(record));
// Add each record to peroperty named Positions
LoadPositionsData().ForEach(record => Positions.Add(record));
Command = new RelayCommand(param => EditData());
}
public ICommand Command { get; }
private void EditData()
{
// Update records in MySQL using dapper
DapperPlusManager.Entity<Person>().Table("Person").Identity(x => x.PersonId);
DapperPlusManager.Entity<Position>().Table("Position").Identity(x => x.PositionId);
using(MySqlConnection conn = new MySqlConnection(connString))
{
conn.BulkUpdate(People, x => x.Position);
}
}
#region Prop Changed
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
View
<StackPanel>
<DataGrid ItemsSource="{Binding People}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
<DataGridTemplateColumn Header="Position Title">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Path=DataContext.Positions,
RelativeSource={RelativeSource AncestorType=DataGrid}}"
DisplayMemberPath="PositionTitle"
SelectedValue="{Binding Path=Position, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Content="Save new data" Command="{Binding Command}" />
</StackPanel>
I think I've got it. What I noticed is in the documentation example:
This loop
So I changed my EditData method to the following code:
private void EditData()
{
foreach(var item in People)
{
item.PositionId = item.Position.PositionId;
}
// Update records in MySQL using dapper
DapperPlusManager.Entity<Person>().Table("Person").Identity(x => x.PersonId);
DapperPlusManager.Entity<Position>().Table("Position").Identity(x => x.PositionId);
using(MySqlConnection conn = new MySqlConnection(connString))
{
conn.BulkUpdate(People, x => x.Position);
}
}
and also added a Property in the Person model
public int PositionId { get; set; }