C#可以非常快速地将数千行从文本文件添加到数据库

时间:2011-02-15 16:45:53

标签: c# sql-server sql-server-2008 web-applications webforms

我正在为Grepolis创建一个应用程序,这是一款在线战争游戏,您可以与数千名其他玩家一起玩游戏。我正在http://en12.grepolis.com/data/players.txt连接到一个文本文件并将其下载到WebClient.DownloadString中。然后我将其分解为“\ n”并将每个字符串拆分为“,”。每行包含玩家ID,名称,联盟_用户,积分,等级和城镇(玩家拥有的城镇数量)。最后一次计数超过60000。我在大约10分钟内将它们全部上传到本地数据库,现在对每一行进行更新,以便在此过程中删除0点上的所有玩家,并更新自上次更新以来已更改的任何人。问题是,即使只是更新到目前为止已经花了10多分钟。

有没有真正快速的方法来做我想做的事情?以下是我认为相关的所有代码:

文件:Global.asax.cs

protected void Application_Start(object sender, EventArgs e)
{
    WebClient wc = new WebClient();
    String str = wc.DownloadString("http://en12.grepolis.com/data/players.txt");
    String[] players = str.Split('\n');
    foreach (String player in players)
    {
        String[] playerInfo = player.Split(',');
        ContentManager cm = new ContentManager();
        int id = 0;
        String name = "";
        int alliance_id = 0;
        int points = 0;
        int rank = 0;
        int towns = 0;
        try
        {
            int.Parse(playerInfo[0]);
            id = int.Parse(playerInfo[0]);
        }
        catch
        {
        }
        try
        {
            name = playerInfo[1];
        }
        catch
        {
        }
        try
        {
            int.Parse(playerInfo[2]);
            alliance_id = int.Parse(playerInfo[2]);
        }
        catch
        {
        }
        try
        {
            int.Parse(playerInfo[3]);
            points = int.Parse(playerInfo[3]);
        }
        catch
        {
        }
        try
        {
            int.Parse(playerInfo[4]);
            rank = int.Parse(playerInfo[4]);
        }
        catch
        {
        }
        try
        {
            int.Parse(playerInfo[5]);
            towns = int.Parse(playerInfo[5]);
        }
        catch
        {
        }
        if (points > 0 && towns > 0 && id > 0 && !name.Equals(""))
        {
            try
            {
                cm.UpdatePlayer(id, name, alliance_id, points, rank, towns);
            }
            catch
            {
            }
        }
        else
        {
            try
            {
                cm.DeletePlayer(id);
            }
            catch
            {
            }
        }
    }
}

文件:ContentManager.cs

public class ContentManager : IHttpModule
{
    SqlDataSource conn = new SqlDataSource(WebConfigurationManager.ConnectionStrings["DevConn"].ConnectionString, "");
    public void UpdatePlayer(int id, String name, int alliance_id, int points, int rank, int towns) {
        conn.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;
        conn.UpdateCommand = "UpdatePlayer";
        conn.UpdateParameters.Clear();
        conn.UpdateParameters.Add("id", id.ToString());
        conn.UpdateParameters.Add("name", name);
        conn.UpdateParameters.Add("alliance_id", alliance_id.ToString());
        conn.UpdateParameters.Add("points", points.ToString());
        conn.UpdateParameters.Add("rank", rank.ToString());
        conn.UpdateParameters.Add("towns", towns.ToString());
        conn.Update();
    }

    public void DeletePlayer(int id)
    {
        conn.DeleteCommandType = SqlDataSourceCommandType.StoredProcedure;
        conn.DeleteCommand = "DeletePlayer";
        conn.DeleteParameters.Clear();
        conn.DeleteParameters.Add("id", id.ToString());
        conn.Delete();
    }
}

2 个答案:

答案 0 :(得分:3)

您一次处理一个玩家,您需要进行批量上传。

您需要处理FOR循环中的所有用户,然后执行“批量插入”。

在我的工作中,我可以以我的HD可以读取的速度批量插入。

警告提示,批量插入会锁定表格,因此如果您计划在导入过程中使表格可读,则可能必须为批量插入设置批次。

例如:100k行,10k批次。 1)锁定表 2)开始导入直到10k行 3)解锁表 4)如果要提交更多行,请转到1

在第3步和第4步之间,会有一个中断,其他查询可能针对该表运行。

SQL和.NET管理几乎所有这些,我刚刚为你打破了逻辑。您需要做的就是阅读批量插入和批处理,一旦获得它就会很容易。

答案 1 :(得分:2)

每当我不得不这样做时,我已将数据输出到临时文本文件,然后使用Bulk Insert将数据转储到数据库中。