我正在申请某个网站。该网站有很多玩家,我抓了他们的个人资料页面。他们的个人资料页面包含姓名,级别,世界和上次登录日期等信息。
所以我创建了一个名为Player的对象。然后我将所有数据添加到列表中。
public static List<Player> Players = new List<Player> { };
public class Player
{
public string Name { get; set; }
public string Sex { get; set; }
public string Vocation { get; set; }
public int Level { get; set; }
public int Achievements { get; set; }
public string World { get; set; }
public string LastLogin { get; set; }
public string AccountStatus { get; set; }
public int OnlineStatus { get; set; }
}
我添加如下数据:
new Player { Name = playerName, Sex = playerSex, Vocation = playerVocation, Level = playerLevel, Achievements = playerAchievements, World = playerWorld, LastLogin = playerLastLogin, AccountStatus = playerAccountStatus, OnlineStatus = playerOnlineStatus };
我现在想将所有播放器添加到我的MySQL数据库中,但我似乎无法理解如何插入数据。
我建立了一个连接,我尝试SELECT数据,它工作正常。所以我的联系也不错。但插入似乎不起作用。
这是我添加的代码,用于将数据插入表格中:
string connString = "Server=localhost;Port=3306;Database=rookstat;Uid=XXXXXXX;password=XXXXXX;";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
foreach (Player rooker in Players)
{
command.CommandText = "Insert into rookstayers (id, name, sex, vocation, level, achievements, world, lastlogin, accountstatus, onlinestatus) values('', rooker.Name, rooker.Sex, rooker.Vocation, rooker.Level, rooker.Achievements, rooker.World, rooker.LastLogin, rooker.AccountStatus, rooker.OnlineStatus)";
conn.Open();
command.ExecuteNonQuery();
}
conn.Close();
我做错了什么?我不确定我插入的值。它应该是rooker.Name还是什么?
答案 0 :(得分:6)
构建查询的方式会创建一个字符串,并将变量名称视为文字字符串。
相反,您需要像这样的参数化查询
string connString = "Server=localhost;Port=3306;Database=rookstat;Uid=XXXXXXX;password=XXXXXX;";
using(MySqlConnection conn = new MySqlConnection(connString))
using(MySqlCommand command = conn.CreateCommand())
{
conn.Open();
command.CommandText = @"Insert into rookstayers
(id, name, sex, vocation, level, achievements,
world, lastlogin, accountstatus, onlinestatus)
values('', @name, @sex, @vocation, @level, @Achievements,
@World, @LastLogin, @AccountStatus, @OnlineStatus)";
command.Parameters.Add("@name", MySqlDbType.VarChar);
command.Parameters.Add("@sex", MySqlDbType.VarChar);
command.Parameters.Add("@vocation", MySqlDbType.VarChar);
command.Parameters.Add("@level", MySqlDbType.Int32);
.... and so on for all the parameters placeholders
command.Prepare();
foreach (Player rooker in Players)
{
command.Parameters["@name"].Value = rooker.Name;
command.Parameters["@sex"].Value = rooker.Sex;
command.Parameters["@vocation"].Value = rooker.Vocation;
command.Parameters["@level"].Value = rooker.Level;
... and so on for the other parameters defined
command.ExecuteNonQuery();
}
}
这样,在进入循环之前,您可以定义sql命令并在MySqlCommand Parameters集合中创建参数而不设置值。并且,如下所述,Mr先添加了对命令的调用.Prepare可以提高性能。
在循环内部,对于定义的每个参数,您可以设置其值并调用命令来执行。
我还希望指向using语句,确保正确关闭和处理对象,并使用Add为每个参数设置适当的参数类型而不是AddWithValue。 AddWithValue是一个有许多缺点的快捷方式,您可以在本文Can we stop using AddWithValue already?
中阅读最后一条建议,如果对象和数据之间的这种转换经常发生,那么你应该投入一点时间来学习使用像Dapper这样的ORM工具
编辑:看看你的整个代码,你似乎错过了一个重要的步骤。您需要将播放器添加到播放器列表
private async void insertTimer_Tick(object sender, EventArgs e)
{
if (onlineList.Items.Count > 0)
{
for (int i=0; i<onlineList.Items.Count; i++)
{
CurrentPlayer = onlineList.Items[i].ToString();
var playerProfile = await GetData();
foreach (var row in playerProfile)
{
.... gets player data ....
}
// Creates a new Player and add to the insertion list
Players.Add(new Player
{
Name = playerName,
Sex = playerSex,
Vocation = playerVocation,
Level = playerLevel,
Achievements = playerAchievements,
World = playerWorld,
LastLogin = playerLastLogin,
AccountStatus = playerAccountStatus,
OnlineStatus = playerOnlineStatus
};
}
// And now the inserts goes here
.......
答案 1 :(得分:4)
您正在将字符串文字传递给查询,而不是变量值:
尝试将您的查询调整为:
command.CommandText = "Insert into rookstayers (id, name, sex, vocation) values('', @name, @sex, @vocation)";
然后Parameters.AddWithValue
如下所示:
command.Parameters.AddWithValue("@name", rooker.Name);
command.Parameters.AddWithValue("@sex", rooker.Sex);
command.Parameters.AddWithValue("@vocation", rooker.Vocation);
等
这也有助于防止SQL注入。
答案 2 :(得分:2)
尝试以下方法:
*4
请注意差异: