用于访问数据表记录的C#代码优化

时间:2009-10-05 18:40:13

标签: c# asp.net optimization dictionary datatable

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

我有一个数据表,样本值是这样的:

列:id,user_id,starttime,endtime

行样本:1,5,5.0.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(object sender,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;
    }

3 个答案:

答案 0 :(得分:6)

  

数据表有超过一千行,函数必须被调用近一千次

有你的问题。如果我正确读取,那么您将遍历问题中未显示的其他一些数据集合中的每个项目的整个数据表。

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

如果这不是一个选项,你仍然希望以某种方式重新处理它,这样你只需要整理一次。如果你正在使用c#,你可以通过linq查询(甚至只是IEnumerable扩展+ lambda方法)来实现。

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

答案 1 :(得分:1)

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

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

的LINQ:

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

void RunMyFunction(DataRow row)
{

}

答案 2 :(得分:0)

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

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; }
}