如何处理来自 sqlite 查询的数据?
How to handle data from sqlite query?
我有一个获取以下数据的 sqlite 查询:
private GetAllPlayerAttributesFromDB()
{
IDbCommand dbcmd = dbconn.CreateCommand();
string sqlQueryPlayer = "SELECT player_id, ability_id, value FROM playerabilities";
dbcmd.CommandText = sqlQueryPlayer;
IDataReader reader = dbcmd.ExecuteReader();
IDictionary<int, int> dict = new Dictionary<int, int>();
while (reader.Read())
{
int player_id = reader.GetInt32(0);
int ability_id = reader.GetInt32(1);
int value= reader.GetInt32(2);
// I have no idea how to save the data now
dict.Add(ability_id, value);
}
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
}
╔════════════╦════════════╦═══════╗
║ player_id ║ ability_id ║ value ║
╠════════════╬════════════╬═══════╣
║ "16" ║ "0" ║ "56" ║
║ "16" ║ "1" ║ "52" ║
║ "16" ║ "2" ║ "62" ║
║ "16" ║ "3" ║ "72" ║
║ "16" ║ "4" ║ "64" ║
║ "28" ║ "0" ║ "41" ║
║ "28" ║ "1" ║ "49" ║
║ "28" ║ "2" ║ "55" ║
║ "28" ║ "3" ║ "60" ║
║ "28" ║ "4" ║ "65" ║
║ "41" ║ "0" ║ "72" ║
║ "41" ║ "1" ║ "71" ║
║ "41" ║ "2" ║ "79" ║
║ "41" ║ "3" ║ "84" ║
║ "41" ║ "4" ║ "52" ║
╚════════════╩════════════╩═══════╝
我希望如何使用数据:
我想通过使用他的 player_id 作为关键从一名球员那里获得所有能力和价值。例如,如果我需要来自玩家 16 的数据,那么我想获得 (0, 56), (1,52), (2, 62)... 或具有 int[] 值 = [56, 52,每个玩家 62, 72, 64]。
现在我想以高效的方式保存这些数据。在 PHP 中,我会使用关联数组。我怎么能在 C# 中做到这一点? (我读过一些关于字典的例子,但我不能用它们来解决我的问题。也许字典是错误的方法?)
对于您已有的代码,最简单的事情可能是填充 DataTable
,即 in-memory "table"。它有行和列。
IDataReader reader = dbcmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
Update
加载数据 table 后,您可以将数据转换为玩家实例(例如)。
鉴于这些 classes:
class PlayerDetails
{
public string AbilityID { get; set; }
public string Value { get; set; }
}
class Player
{
public string PlayerID { get; set; }
public List<PlayerDetails> Details { get; set; }
}
您可以获得一个 List<Player>
,每个 Details
属性 包含一个 List<PlayerDetails>
:
var groupedByPlayer = dt.AsEnumerable().GroupBy(d => d["player_id"]).Select(b => new
Player
{
PlayerID = b.Key.ToString(),
Details = b.Select(bp => new PlayerDetails
{
AbilityID = bp[1].ToString(),
Value = bp[2].ToString()
}).ToList()
});
如果您不熟悉 Linq,那可能看起来很难看,但如果您了解 SQL GROUP BY,除了您最终得到 Player
class 的实例外,它很相似.
您需要定义一个数据结构来保存您的数据。
一个简单的 class 代表一行
public class Player
{
public int Id {get; set;}
public int Ability {get;set;}
public int Value {get;set;}
}
并将每一行添加到 List<Player>
。
但是,那么每个玩家将有 5 行。
另一种选择是 class 仅 Ability/Value
public class AbilityValue
{
public int Ability {get;set;}
public int Value {get;set;}
}
并将其存储在 Dictionary<int, List<AbilityValue>>
中。这需要一些解释:
- 关键是player_id
- 该值是您阅读的 ability/value 对列表
使用方法:
- 从数据中读取一行
- 查看您的字典中是否已有该关键字
- 如果是,请将新 ability/value 添加到该列表
- 如果没有,请添加一个新项目,并以 player_id 为键。不要忘记初始化该列表
如果您知道 "Ability" 始终介于 0 和 4 之间,您还可以使用大小为 5 的数组作为字典的值。然后使用该能力作为该数组的索引来设置值。
我有一个获取以下数据的 sqlite 查询:
private GetAllPlayerAttributesFromDB()
{
IDbCommand dbcmd = dbconn.CreateCommand();
string sqlQueryPlayer = "SELECT player_id, ability_id, value FROM playerabilities";
dbcmd.CommandText = sqlQueryPlayer;
IDataReader reader = dbcmd.ExecuteReader();
IDictionary<int, int> dict = new Dictionary<int, int>();
while (reader.Read())
{
int player_id = reader.GetInt32(0);
int ability_id = reader.GetInt32(1);
int value= reader.GetInt32(2);
// I have no idea how to save the data now
dict.Add(ability_id, value);
}
reader.Close();
reader = null;
dbcmd.Dispose();
dbcmd = null;
}
╔════════════╦════════════╦═══════╗
║ player_id ║ ability_id ║ value ║
╠════════════╬════════════╬═══════╣
║ "16" ║ "0" ║ "56" ║
║ "16" ║ "1" ║ "52" ║
║ "16" ║ "2" ║ "62" ║
║ "16" ║ "3" ║ "72" ║
║ "16" ║ "4" ║ "64" ║
║ "28" ║ "0" ║ "41" ║
║ "28" ║ "1" ║ "49" ║
║ "28" ║ "2" ║ "55" ║
║ "28" ║ "3" ║ "60" ║
║ "28" ║ "4" ║ "65" ║
║ "41" ║ "0" ║ "72" ║
║ "41" ║ "1" ║ "71" ║
║ "41" ║ "2" ║ "79" ║
║ "41" ║ "3" ║ "84" ║
║ "41" ║ "4" ║ "52" ║
╚════════════╩════════════╩═══════╝
我希望如何使用数据: 我想通过使用他的 player_id 作为关键从一名球员那里获得所有能力和价值。例如,如果我需要来自玩家 16 的数据,那么我想获得 (0, 56), (1,52), (2, 62)... 或具有 int[] 值 = [56, 52,每个玩家 62, 72, 64]。
现在我想以高效的方式保存这些数据。在 PHP 中,我会使用关联数组。我怎么能在 C# 中做到这一点? (我读过一些关于字典的例子,但我不能用它们来解决我的问题。也许字典是错误的方法?)
对于您已有的代码,最简单的事情可能是填充 DataTable
,即 in-memory "table"。它有行和列。
IDataReader reader = dbcmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
Update
加载数据 table 后,您可以将数据转换为玩家实例(例如)。
鉴于这些 classes:
class PlayerDetails
{
public string AbilityID { get; set; }
public string Value { get; set; }
}
class Player
{
public string PlayerID { get; set; }
public List<PlayerDetails> Details { get; set; }
}
您可以获得一个 List<Player>
,每个 Details
属性 包含一个 List<PlayerDetails>
:
var groupedByPlayer = dt.AsEnumerable().GroupBy(d => d["player_id"]).Select(b => new
Player
{
PlayerID = b.Key.ToString(),
Details = b.Select(bp => new PlayerDetails
{
AbilityID = bp[1].ToString(),
Value = bp[2].ToString()
}).ToList()
});
如果您不熟悉 Linq,那可能看起来很难看,但如果您了解 SQL GROUP BY,除了您最终得到 Player
class 的实例外,它很相似.
您需要定义一个数据结构来保存您的数据。
一个简单的 class 代表一行
public class Player
{
public int Id {get; set;}
public int Ability {get;set;}
public int Value {get;set;}
}
并将每一行添加到 List<Player>
。
但是,那么每个玩家将有 5 行。
另一种选择是 class 仅 Ability/Value
public class AbilityValue
{
public int Ability {get;set;}
public int Value {get;set;}
}
并将其存储在 Dictionary<int, List<AbilityValue>>
中。这需要一些解释:
- 关键是player_id
- 该值是您阅读的 ability/value 对列表
使用方法:
- 从数据中读取一行
- 查看您的字典中是否已有该关键字
- 如果是,请将新 ability/value 添加到该列表
- 如果没有,请添加一个新项目,并以 player_id 为键。不要忘记初始化该列表
如果您知道 "Ability" 始终介于 0 和 4 之间,您还可以使用大小为 5 的数组作为字典的值。然后使用该能力作为该数组的索引来设置值。