You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双人在线音乐播放器SQL操作、播放删除功能及代码优化咨询

一、歌曲播放完成后的SQL删除实现

要实现播放完成后同步删除ListBox和SQL数据库中的歌曲,需分两步执行:

1. SQL端删除逻辑

通过参数化的DELETE语句删除Playlist表中对应ID的歌曲记录,避免SQL注入风险:

private void DeletePlayedSong(int songId)
{
    // 1. 删除SQL Playlist表中的目标歌曲
    using (MySqlCommand deleteCmd = new MySqlCommand("DELETE FROM playlist WHERE ID = @SongId", MyCon))
    {
        deleteCmd.Parameters.AddWithValue("@SongId", songId);
        deleteCmd.ExecuteNonQuery();
    }

    // 2. 从ListBox移除对应歌曲(假设LB_Playlist存储歌曲名)
    for (int i = LB_Playlist.Items.Count - 1; i >= 0; i--)
    {
        if (LB_Playlist.Items[i].ToString() == lstSongName[songId])
        {
            LB_Playlist.Items.RemoveAt(i);
            break;
        }
    }

    UpdateUI();
}

2. 触发删除的时机

监听播放器的播放状态变化事件,当歌曲播放完成(状态变为停止且之前处于播放状态)时调用删除方法:

private void Player_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
    // 判定为播放完成的状态:从播放转为停止
    if (e.newState == 8 && Player.playState == WMPLib.WMPPlayState.wmppsStopped)
    {
        // currentPlayingSongId需在播放时提前保存
        DeletePlayedSong(currentPlayingSongId);
    }
}

二、现有代码规范评估与优化建议

1. Button_Add_Click方法问题与优化

存在的问题

  • ID截取逻辑极不稳定:依赖固定字符串位置(startIndex=2、length=3),一旦ListBox显示格式变化(如ID位数增减、前缀字符改变),会直接取错ID或报错。
  • 数据库资源未正确释放:MySqlCommand未用using管理,可能导致连接泄漏;AbrufLeser.Close()位置不合理,若之前未打开会引发异常。
  • 耦合性过高:依赖全局集合lstSongName、lstSongPfad,数据维护成本高,易出错。

优化后代码

建议绑定自定义实体到ListBox,避免字符串解析:

// 定义歌曲实体类
public class Song
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Author { get; set; }
    public string Path { get; set; }

    // 自定义显示文本,兼顾用户可读性和数据完整性
    public override string ToString() => $"[{ID}] {Name} - {Author}";
}

// 优化后的添加按钮逻辑
private void Button_Add_Click(object sender, EventArgs e)
{
    if (LB_Liste.SelectedItem is Song selectedSong)
    {
        using (MySqlCommand insertCmd = new MySqlCommand("INSERT INTO playlist (ID, Name, Path, Que) VALUES (@ID, @Name, @Path, @Que)", MyCon))
        {
            insertCmd.Parameters.AddWithValue("@ID", selectedSong.ID);
            insertCmd.Parameters.AddWithValue("@Name", selectedSong.Name);
            insertCmd.Parameters.AddWithValue("@Path", selectedSong.Path);
            insertCmd.Parameters.AddWithValue("@Que", 0);
            insertCmd.ExecuteNonQuery();
        }

        LB_Playlist.Items.Add(selectedSong.Name);
        UpdateUI();
    }
}

2. Button_Play_Click方法问题与优化

存在的问题

  • 逻辑错误:while循环遍历所有Playlist记录,但仅保留最后一条数据,实际应取排序后的第一条(待播放的第一首)。
  • 资源管理缺失:MySqlCommand、MySqlDataReader未用using自动释放,易导致连接池耗尽。
  • 无异常处理:数据库查询失败时直接崩溃,无友好提示。
  • 未保存播放ID:播放完成后无法准确定位要删除的歌曲。

优化后代码

private int currentPlayingSongId; // 保存当前播放歌曲的ID,供删除时使用

private void Button_Play_Click(object sender, EventArgs e)
{
    try
    {
        // 只查询排序后的第一首待播放歌曲
        using (MySqlCommand queryCmd = new MySqlCommand("SELECT ID, Name, Path FROM playlist ORDER BY que LIMIT 1", MyCon))
        {
            using (MySqlDataReader reader = queryCmd.ExecuteReader())
            {
                if (reader.Read())
                {
                    currentPlayingSongId = Convert.ToInt32(reader["ID"]);
                    string playPath = reader["Path"].ToString();

                    Player.URL = playPath;
                    TimerR.Start();
                    Timer_GIf.Start();
                    UpdateUI();
                }
                else
                {
                    MessageBox.Show("播放列表为空");
                }
            }
        }
    }
    catch (MySqlException ex)
    {
        MessageBox.Show($"数据库查询失败:{ex.Message}");
    }
}

通用优化建议

  • 封装数据库操作:将所有SQL操作(查询、增删)集中到单独的数据库工具类,避免UI层直接操作数据库,降低耦合。
  • 使用ORM框架:推荐Dapper或Entity Framework Core,简化SQL编写,提升代码可读性和可维护性。
  • 全局变量替换:避免直接使用全局的MyCon、AbrufKommando等,改用局部变量+using管理,或封装到数据库类中。
  • 完善异常处理:所有数据库操作添加try-catch,捕获特定异常并给出用户友好提示。

内容的提问来源于stack exchange,提问作者ConflictMeow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 15:35:21