2016-03-22 15 views
0

タイムスタンプを昇順に並べるタブ区切りファイルがあります。各行には7つの列があります。各列はパラメータです。Sqlite INSERTの順序を保持する方法

バルクINSERTコマンドのパラメータとして、タブファイルの行をINSERTするsqliteデータベースがあります。たとえば:

public void Create(IEnumerable<Game> items) 
{ 
    var sbFields = new StringBuilder(); 
    sbFields.Append("ID,"); 
    sbFields.Append("LEAGUE,"); 
    sbFields.Append("VISITORTEAM,"); 
    sbFields.Append("HOMETEAM,"); 
    sbFields.Append("DATETIME,"); 
    sbFields.Append("VISITORSCORE,"); 
    sbFields.Append("HOMESCORE"); 

    int numAppended = 7; 

    var sbParams = new StringBuilder(); 
    for (int i = 1; i <= numAppended; i++) 
    { 
     sbParams.Append("@param"); 
     sbParams.Append(i); 

     if (i < numAppended) 
     { 
      sbParams.Append(", "); 
     } 
    } 

    using (var command = new SQLiteCommand(Db)) 
    { 
     command.CommandText = "INSERT OR IGNORE INTO GAMES (" + sbFields + ") VALUES(" + sbParams + ")"; 
     command.CommandType = CommandType.Text; 

     using (var transaction = Db.BeginTransaction()) 
     { 
      foreach (var game in items) 
      { 
       command.Parameters.Add(new SQLiteParameter("@param1", game.Id)); 
       command.Parameters.Add(new SQLiteParameter("@param2", game.League)); 
       command.Parameters.Add(new SQLiteParameter("@param3", game.VisitorTeam)); 
       command.Parameters.Add(new SQLiteParameter("@param4", game.HomeTeam)); 
       command.Parameters.Add(new SQLiteParameter("@param5", game.Date.Ticks)); 
       command.Parameters.Add(new SQLiteParameter("@param6", game.VisitorScore)); 
       command.Parameters.Add(new SQLiteParameter("@param7", game.HomeScore)); 

       command.ExecuteNonQuery(); 
      } 

      transaction.Commit(); 
     } 
    } 
} 

私はそれが私が(時系列順に)INSERTをしましたが、ではないのと同じ順序になり、データベースからゲームのリストを取得するときと予想さ:実際にそれがですほとんど無作為の順序で現れるもの。このため、データベースから読み込んだら、ゲームリストを並べ替える必要があります。そして、この操作は非常に遅いです。私はソートしたくありません。私はINSERTと同じ順序でそれを読んでいます。

これは可能ですか?注:私はではありませんは、順序を示す新しいパラメータ(列)を追加します。それは私の将来の問題を懇願する人工的な解決策のようだ。ここで

は、私は、データベースからそれを読む方法です。ここで

public IEnumerable<Game> Read() 
{ 
    List<Game> enumerable = new List<Game>(); 

    using (var command = new SQLiteCommand(Db)) 
    { 
     command.CommandText = "SELECT * FROM GAMES"; 
     command.CommandType = CommandType.Text; 

     using (var reader = command.ExecuteReader()) 
     { 
      while (reader.Read()) 
      { 
       Game game = new Game(); 

       game.Id = reader.GetInt32(0); 
       game.League = reader.GetString(1); 
       game.VisitorTeam = reader.GetString(2); 
       game.HomeTeam = reader.GetString(3); 
       game.Date = new DateTime(reader.GetInt64(4)); 
       //game.Date = DateTime.FromFileTimeUtc(Convert.ToInt64(reader.GetInt64(4))); 
       game.VisitorScore = Convert.ToInt32(reader.GetInt32(5)); 
       game.HomeScore = Convert.ToInt32(reader.GetInt32(6)); 

       enumerable.Add(game); 
      } 
     } 
    } 

    return enumerable; 
} 

は、表が作成することです:

public void CreateTable() 
{ 
    string sql = 
     @"CREATE TABLE IF NOT EXISTS GAMES(
             ID    INTEGER      PRIMARY KEY,            
             LEAGUE   TEXT      NOT NULL,                 
             VISITORTEAM  TEXT      NOT NULL,                 
             HOMETEAM  TEXT      NOT NULL,                 
             DATETIME  INTEGER      NOT NULL, 
             VISITORSCORE INTEGER      NOT NULL, 
             HOMESCORE  INTEGER      NOT NULL 
             )"; 

    // if the database table already exists, this will throw an exception. 
    using (var command = new SQLiteCommand(sql, Db)) 
    { 
     command.ExecuteNonQuery(); 
    } 
} 

どのように現在のソート(遅すぎる)

public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource, TKey> 
(this IEnumerable<TSource> source, 
Func<TSource, TKey> keySelector, 
bool descending) 
    { 
     return descending ? source.OrderByDescending(keySelector) 
          : source.OrderBy(keySelector); 
    } 

使い方:

games = games.OrderByWithDirection(x => x.Date.Ticks, false).ToList(); 
+0

SELECT * FROM GAMES ORDER BY ID –

+0

IDはハッシュであり、注文は保証されません – sapbucket

+0

テーブル定義を表示します。 –

答えて

0

データベースに「年代順の昇順タイムスタンプ」を挿入しないで、結果を取得するときにその列で並べ替える理由はありますか?

データベースの順序に基づいてリストの順序を維持することはお勧めできません。列と行の順序は問わず、データベースはそれを気にせず、どちらもあなたには関係ありません。

私はプロジェクトで同様の問題を抱えていました。最後に、避けたいソリューション、つまりインデックスの列に行きました。これは私が望んでいたインデックスを変更する必要があったためです。そして、はい、私は解決策が嫌であることに同意します。

+0

テーブル内のDateTimeは、1900年1月1日以降の数字のティックです。これを素早くソートする方法はありますか?私は現在、ソートのために投稿に追加したコードスニペットを使用しています(上記参照)。それは非常に遅いです。 – sapbucket

+0

SQLクエリのその列で並べ替えるだけです。 command.CommandText = "SELECT * FROM GAMES ORDER BY DATETIME"; – naslund

+0

私は100kのダミー "ゲーム"を使ってソート方法を試してみましたが、パフォーマンスは低下しませんでした。そのリストをソートするのに32ミリ秒かかりました(現実的な値は即時にソートされていました)ので、ここで問題を特定したかどうかはわかりません。 – naslund

関連する問題