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; }