【问题标题】:C# code optimization for accessing datatable records用于访问数据表记录的 C# 代码优化
【发布时间】:2009-10-05 18:40:12
【问题描述】:

我的数据表存在成本问题。我需要用更智能的代码替换代码。

我有一个数据表,样本值如下:

列:id、user_id、开始时间、结束时间

行样本:1 , 5, 05.10.2009 08:00:00,05.10.2009 17:00

我的伪代码是

    function something()
    {
    for(int i=0;i<datatable.Rows.Length;i++)
    {
    if(Someobject.variable.Equals(dt.Rows[i][user_id].ToString()))
    {
    if(Date.Compare(somevariable,dt.Rows[i][starttime].ToString())!=0)
    {
    //Do something
    }
    }
    }
}

就是这样。数据表有一千多行,在asp.net页面加载时,函数要调用近千次。

所以我必须改变它。

我考虑过使用字典,但它似乎只需要两个变量。你能给我什么建议。

编辑:

我还不能解决问题。这是相关的代码。提前致谢。

protected void RadScheduler_Randevu_TimeSlotCreated(对象发送者,Telerik.Web.UI.TimeSlotCreatedEventArgs e) {

for (int i = 0; i < calismaSaatleridt.Rows.Count; i++)
{
    if (RadScheduler_Randevu.SelectedView.Equals(SchedulerViewType.DayView))
    {
        if (RadScheduler_Randevu.SelectedDate.ToShortDateString().Equals(Convert.ToDateTime(calismaSaatleridt.Rows[i]["calisma_baslangic"]).ToShortDateString()))
        {
            if (e.TimeSlot.Resource.Key.ToString().Equals(calismaSaatleridt.Rows[i]["hekim_id"].ToString()))
            {
                if (DateTime.Compare(e.TimeSlot.Start, Convert.ToDateTime(calismaSaatleridt.Rows[i]["calisma_baslangic"])) < 0 || DateTime.Compare(e.TimeSlot.End, Convert.ToDateTime(calismaSaatleridt.Rows[i]["calisma_bitis"])) > 0)
                {
                    e.TimeSlot.CssClass = "Disabled";
                }
            }
        }
    }
}

}

这是返回结果集的函数。

private DataTable calismaSaatiGetir(string yonetici_id)
    {
        SqlConnection connection = new SqlConnection();
        connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        SqlCommand command = new SqlCommand();
        command.CommandText = "select calisma_saati.id,kullanici.id as hekim_id,LEFT(CONVERT(VARCHAR,calisma_saati.tarih,104),10)+ ' ' +LEFT(CONVERT(VARCHAR,calisma_saati.baslangic_saati,108),5) AS calisma_baslangic,LEFT(CONVERT(VARCHAR,calisma_saati.tarih,104),10)+ ' '+LEFT(CONVERT(VARCHAR,calisma_saati.bitis_saati,108),5) AS calisma_bitis from calisma_saati JOIN kullanici ON kullanici.id=calisma_saati.kullanici_id WHERE  yonetici_id='" +  Session["yonetici"].ToString() + "' ";
        command.Connection = connection;
        connection.Open();
        SqlDataAdapter da = new SqlDataAdapter(command.CommandText, connection);
        DataSet ds = new DataSet();
        da.Fill(ds, "calisma_saati");
        calismaSaatleridt = ds.Tables["calisma_saati"];
        connection.Close(); 
        return calismaSaatleridt;
    }

【问题讨论】:

    标签: c# asp.net optimization dictionary datatable


    【解决方案1】:

    数据表有一千多行,函数要调用近千次

    你的问题。如果我没看错,那么您正在循环遍历问题中未显示的其他数据集合中的每个项目的整个数据表。

    解决此问题的最佳方法是在数据库级别:无论您正在做什么来生成此数据表,都需要了解您的其他数据集,以便您可以在数据库中考虑到它(并利用诸如索引和缓存数据之类的东西)。这可能意味着编写一个比您习惯的要复杂得多的选择查询,但这是正确的做法。

    如果这不是一个选项,您仍然希望以某种方式重新工作,以便您只对所有内容进行一次交互。如果您使用的是 c#,您可能可以通过 linq 查询(甚至只是 IEnumerable 扩展 + lambda 方法)来完成此操作。

    关于使用字典:它可能只需要两个变量,但其中一个变量可能是更复杂的对象,例如表中的整个数据行。无论哪种方式,为了向您提供示例代码之类的任何内容,我们都需要更好地了解其他数据的外观以及您的预期结果。

    【讨论】:

    • 是的,我完全同意你的观点,循环是真正的问题。情况是这样的:我有一个 radscheduler 组件,它有一个时隙创建事件。在页面加载时,我需要根据用户检查该时隙是启用还是禁用。该事件被调用了近一千次。所以我不能改变它。我必须做的是尽可能快地从数据表或其他东西中获取。我明天可以粘贴示例代码和示例数据,但现在我没有。也谢谢你的回答。
    • 在这种情况下,您可能希望在获取数据表后立即构建字典,并将其保存在良好且公开的地方,这样您就不必继续返回数据库它。
    【解决方案2】:

    这是直接来自数据库吗?如果是这样,为什么不直接执行查询以获得更具体的结果集呢?然后你可以使用 linq 在每一行上执行你的函数。

    更多定义的 SQL: select * from table where userID = 'bob' and starttime between '1/1/2009 11:00 PM' 和 '1/1/2009 11:21 PM'

    林克:

    DataTable table = getFromDb();
    table.Rows.Cast<DataRow>().ToList().ForEach(x => RunMyFunction(x));
    
    void RunMyFunction(DataRow row)
    {
    
    }
    

    【讨论】:

    • 是的,数据表是从数据库查询中填充的。实际上有一个组件的时间段,在时间段创建事件中,我需要检查用户是否在开始时间和结束时间之间工作,所以我禁用了时间段。我不知道我可以用 linq 做到这一点。你能给我一个样品吗?
    【解决方案3】:

    这个怎么样? (如果您可以将此查询推送到数据库会更好。但这比循环每一行要快)

    void something(DataTable dt, myobj Someobject, DateTime somevariable)
    {
        string filterPattern = "user_id='{0}' AND starttime='{1}'";
        string filter = string.Format(filterPattern, 
                                      Someobject.variable, 
                                      somevariable);
        DataRow[] rows = dt.Select(filter);
    
        foreach (DataRow row in rows)
            DoSomething(row);
    }
    void DoSomething(DataRow row)
    {
    }
    public class myobj
    {
        public string variable { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多