我的应用程序就像网络爬虫一样;它让我获得了一些关于特定游戏中玩家的信息。这些信息包括他们的等级和他们的在线状态(在线或离线)。我想要做的是将所有玩家添加到数据库中。但是,如果它们存在,它应该只更新它们已经存在的行。
为此,我决定首先删除数据库中与我要插入的名称相匹配的所有名称。他们的名字存储在@name中。然后,我想将表中的所有人设置为onlinestatus = 0(表示它们处于脱机状态)。然后我想将onlinestatus设置为1,对于我插入的玩家。我目前正在插入的玩家是游戏中唯一在线玩家。因此,如果它们不在我插入的列表中,则它们应该脱机。这就是为什么我首先尝试重置他们的在线状态。
然后我还要将我要插入的所有玩家的等级重置为0。然后在最后我再次插入他们的东西。但它似乎没有起作用,我不知道最好的做事方式。
感谢任何帮助!
我想做什么:
将玩家列表插入数据库
如果它们已经存在于数据库中,请不要插入它们,而只是更新它们的级别和onlinestatus
onlinestatus = 1。这是一个球员名单。如果它们不在列表中,请将它们脱机。
using (var connection = new MySqlConnection(connString))
{
connection.Open();
using (var command = new MySqlCommand())
{
command.Connection = connection;
command.CommandText = @"DELETE FROM rookstayers WHERE name = @name;
UPDATE rookstayers SET onlinestatus CASE WHEN name = @name THEN 1 ELSE 0 END;UPDATE rookstayers SET level = 0 WHERE name = @name; INSERT INTO rookstayers (name, sex, vocation, level, achievements, world, lastlogin, accountstatus, onlinestatus) VALUES (@name, @sex, @vocation, @level, @achievements, @world, @lastLogin, @accountStatus, @onlineStatus)";
command.Prepare();
foreach (var rooker in Players)
{
command.Parameters.Clear();
command.Parameters.AddWithValue("@name", rooker.Name);
command.Parameters.AddWithValue("@sex", rooker.Sex);
command.Parameters.AddWithValue("@vocation", rooker.Vocation);
command.Parameters.AddWithValue("@level", rooker.Level);
command.Parameters.AddWithValue("@achievements", rooker.Achievements);
command.Parameters.AddWithValue("@world", rooker.World);
command.Parameters.AddWithValue("@lastLogin", rooker.LastLogin);
command.Parameters.AddWithValue("@accountStatus", rooker.AccountStatus);
command.Parameters.AddWithValue("@onlineStatus", rooker.OnlineStatus);
command.ExecuteNonQuery();
}
Players.Clear();
}
connection.Close();
}
答案 0 :(得分:3)
你需要这样的东西,因为你的名字是独一无二的。请注意下面的粗略指南。您可以使用MySQL if ($color) {
$content.Foreground = $color
}
$ime.Items.Add($content)
函数。
IF
答案 1 :(得分:2)
删除列表中的所有玩家后,您无法更新它们。
所以你可能需要为表格中的每个人都这样做:
UPDATE rookstayers SET onlinestatus = 0;
UPDATE rookstayers SET level = 0;
答案 2 :(得分:2)
第一个UPDATE语句缺少=
:
UPDATE rookstayers SET onlinestatus CASE WHEN name =
-- Need an equal sign here ------^
此外,我怀疑Parameters.Clear()
电话可能会丢掉一些东西。它实际上删除了集合中的所有参数,当你真正需要做的就是更改值。试试这个:
command.Prepare();
//Guessing a column names/types here. Use actual column types from your DB
command.Parameters.Add("@name", MySqlDbType.VarString, 20);
command.Parameters.Add("@sex", MySqlDbType.VarString, 1);
command.Parameters.Add("@vocation", MySqlDbType.VarString, 20);
command.Parameters.Add("@level", MySqlDbType.Int32);
command.Parameters.Add("@achievements", MySqlDbType.VarString, 255);
command.Parameters.Add("@world", MySqlDbType.VarString, 20);
command.Parameters.Add("@lastLogin", MySqlDbType.DateTime);
command.Parameters.Add("@accountStatus", MySqlDbType.Int32);
foreach (var 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;
command.Parameters["@achievements"].Value = rooker.Achievements;
command.Parameters["@world"].Value = rooker.World;
command.Parameters["@lastLogin"].Value = rooker.LastLogin;
command.Parameters["@accountStatus"].Value = rooker.AccountStatus;
command.Parameters["@onlineStatus"].Value = rooker.OnlineStatus;
command.ExecuteNonQuery();
}
完成这些更改后,请发布您的实际错误,或者您对预期与观察到的结果所看到的内容。
答案 3 :(得分:0)
try
{
using (var connection = new MySqlConnection(connString))
{
connection.Open();
using (var command = new MySqlCommand())
{
command.Connection = connection;
command.CommandText = @"SELECT FROM rookstayers where name = @name";
MySqlDataReader reader = command.ExecuteReader();
foreach (var rooker in Players)
{
while (reader.Read())
{
if (reader.HasRows())
{
command.CommandText = @"UPDATE rookstayers SET onlinestatus CASE WHEN name = @name THEN 1 ELSE 0 END; UPDATE rookstayers SET level = 0 WHERE name = @name";
command.Parameters.AddWithValue("@name", rooker.Name);
command.Parameters.AddWithValue("@onlineStatus", rooker.OnlineStatus);
command.ExecuteNonQuery();
}
else
{
command.CommandText = @"INSERT INTO rookstayers (name, sex, vocation, level, achievements, world, lastlogin, accountstatus, onlinestatus) VALUES (@name, @sex, @vocation, @level, @achievements, @world, @lastLogin, @accountStatus, @onlineStatus)";
command.Parameters.AddWithValue("@name", rooker.Name);
command.Parameters.AddWithValue("@sex", rooker.Sex);
command.Parameters.AddWithValue("@vocation", rooker.Vocation);
command.Parameters.AddWithValue("@level", rooker.Level);
command.Parameters.AddWithValue("@achievements", rooker.Achievements);
command.Parameters.AddWithValue("@world", rooker.World);
command.Parameters.AddWithValue("@lastLogin", rooker.LastLogin);
command.Parameters.AddWithValue("@accountStatus", rooker.AccountStatus);
command.Parameters.AddWithValue("@onlineStatus", "1");
command.ExecuteNonQuery();
}
}
}
}
}
}
finally
{
Players.Clear();
connection.Close();
}
答案 4 :(得分:0)
我认为这是Entity Framework的一个非常好的用例。除非你正在处理大量的表格,否则在这里工作真的很容易。您需要做的就是通过NuGet安装以下软件包并设置app.config以连接到相应的数据库实例。
Nuget包:
EntityFramework
MySql.Data
MySql.Data.Entity
app.config中的连接字符串示例:
<connectionStrings>
<add name="RookstayersDbContext"
connectionString="server=localhost;userid=root;password=mypass;database=mydb"
providerName="MySql.Data.MySqlClient" />
</connectionStrings>
玩家类:
public class Player
{
public int Id { get; set; }
public string Sex { get; set; }
public string Vocation { get; set; }
public int Level { get; set; }
public string Achievements { get; set; }
public string World { get; set; }
public DateTime? LastLogin { get; set; }
public string AccountStatus { get; set; }
public bool IsOnline { get; set; }
}
RookstayersDbContext:
public class RookstayersDbContext : DbContext
{
public RookstayersDbContext() : base("RookstayersDbContext") { }
public DbSet<Player> Players { get; set; }
}
您的ETL代码:
//Replace this with wherever you pull the info from (as a Player entity)
var currentPlayersData = new List<Player>();
using(var ctx = new RookstayersDbContext())
{
//Iterate through your new data collection
foreach(var player in currentPlayersData)
{
var dbPlayer = ctx.Players.FirstOrDefault(x => x.Name == player.Name);
//Insert new player if not existing
if(dbPlayer == null)
{
player.IsOnline = true; //ensure flagged as online
ctx.Players.Add(player); //add new player
continue; //proceed through to next current player
}
//If player already exists, flag as online
dbPlayer.IsOnline = true;
}
//Now iterate through your database collection
foreach(var player in ctx.Players)
{
//If no player information found in current players data, flag as offline
if (!currentPlayersData.Any(x => x.Name == player.Name))
player.IsOnline = false; //flag player as offline
}
//Save any changes made in this context to database
ctx.SaveChanges();
}