在同一个foreach循环中多次使用SQLiteCommand和SQLiteDataReader

时间:2015-07-24 05:46:37

标签: c# wpf sqlite foreach

在我的WPF应用程序中,我在同一个foreach循环中多次使用SQLiteCommand和SQLiteDataReader。这是我正在做的,但它没有按预期工作。我希望得到ArtistSong_tbl中与song_cord_ids数据匹配的所有记录。但是现在我只有单曲。 这是代码。

try
        {
            conn.Open();
            var command = conn.CreateCommand();
            command.CommandText = "SELECT song_id FROM fav_tbl";
            SQLiteDataReader sdr = command.ExecuteReader();

            while(sdr.Read())
            {
                song_cord_ids.Add(sdr.GetString(0));
            }
            sdr.Close();

            if(song_cord_ids.Count>0)
            {

                foreach (var songId in song_cord_ids)
                {
                    command.CommandText = "SELECT * FROM ArtistSong_tbl WHERE Artist_id='" + songId + "'";

                    SQLiteDataReader sdr1 = command.ExecuteReader();
                    if (sdr1.HasRows)
                    {
                        while (sdr1.Read())
                        {
                            favsongs.Add(new Song()
                            {
                                _id = sdr1.GetString(1),
                                title = Crypto_Engine.Decrypt(sdr1.GetString(2), "songcord-ekbana-crypto11"),
                                isTabs = sdr1.GetString(3)
                            });
                        }
                    }
                    else
                    {
                        //ToDo visibility control
                    }
                    sdr1.Close();
                }
                this.FavSongs = favsongs.OrderBy(s=> s.title).ToList();
            }
        }

所以在代码中我有foreach循环并且在那个循环中我从数据库中获取特定的歌曲(通过歌曲id),所以当循环启动1次时它工作正常,在底部我关闭了sdr1(SQLiteDataReader变量)所以在下一个loop command.ExecuteReader()不起作用,因为sdr1变量已经关闭,如果我没有关闭,那么我无法加载另一个命令并在sdr1仍然打开时执行。那我怎么能让它发挥作用呢?

1 个答案:

答案 0 :(得分:2)

您不需要两个读者,您应该使用JOIN重写您的查询:

SELECT
    ArtistSong_tbl.*
FROM
    ArtistSong_tbl JOIN
    fav_tbl ON ArtistSong_tbl.Artist_id = fav_tbl.song_id

然后代码可以像这样重构:

using (var conn = /* create connection */)
{
    conn.Open();
    using (var command = conn.CreateCommand())
    {
        command.CommandText = "[Query text from above]";
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                favsongs.Add(new Song
                {
                    _id = sdr1.GetString(1),
                    title = Crypto_Engine.Decrypt(sdr1.GetString(2), "songcord-ekbana-crypto11"),
                    isTabs = sdr1.GetString(3)
                });            
            }
        }
    }
    this.FavSongs = favsongs.OrderBy(s=> s.title).ToList();
}