Dapper 不更新 MySQL 中具有一对一关系的记录
Dapper not updating records in MySQL with one to one relationship
目标
我打算将记录从 WPF 应用程序更新到 MySQL。
这是加载的数据:
用户可以编辑数据:
单击按钮时,数据应更新:
它检测来自 UI 的更改并显示更新的记录。
问题
查看我的数据库时,我看到列 Name
已更改,但 PositionId
保持不变:
为什么 PositionId
没有更新?我该如何更新它?
代码
型号
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();
}
查看模型
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
}
查看
<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>
我想我明白了。我注意到的是文档示例:
这个循环
所以我将 EditData 方法更改为以下代码:
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);
}
}
并且还在 Person 模型中添加了一个 属性
public int PositionId { get; set; }
目标
我打算将记录从 WPF 应用程序更新到 MySQL。
这是加载的数据:
用户可以编辑数据:
单击按钮时,数据应更新:
它检测来自 UI 的更改并显示更新的记录。
问题
查看我的数据库时,我看到列 Name
已更改,但 PositionId
保持不变:
为什么 PositionId
没有更新?我该如何更新它?
代码
型号
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();
}
查看模型
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
}
查看
<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>
我想我明白了。我注意到的是文档示例:
这个循环
所以我将 EditData 方法更改为以下代码:
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);
}
}
并且还在 Person 模型中添加了一个 属性
public int PositionId { get; set; }