你的位置:首页 > ASP.net教程

[ASP.net教程].Net频繁访问数据库的优化探究(一)


知识点:DataTable、Linq、lamda表达式、Cache

场景:查询部门的所有员工和管理员,并分配相应的权限

实现过程一般为:查询部门,遍历部门(查询员工、分配权限、查询管理员、分配权限)

访问数据库比较频繁的环节为遍历部门里面的查询员工和管理员,所有我们尝试在这里进行优化

1.将用户全部读取出来存入DataTable对象中,下一次可直接从DataTable中查询数据而不必再读取数据库,但即便存入DataTable对象,DataTable对象也会在页面刷新或回发时丢失,所以将DataTable对象存入.Net Cache中。(这与存入Session有质的差别)。

代码:

if (Page.Cache["users"] == null)   Page.Cache.Insert("users", UsersCom.GetSimpleUser(), null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(20));DataTable dt = (DataTable)Page.Cache["users"];

其中Page.Cache.Insert最后两个参数指示缓存到期时间;

UsersCom.GetSimpleUser()是从数据库中查询数据的方法,返回的是DataTable对象。尽量不要返回所有的字段,而是需要的字段。这里返回的字段包括user_id、unit_id。

2.从Cache中查询数据,也就是查询DataTable对象,查询的方法很多,从最简单的开始。

代码:

dt.Select("unit_id=" + unitID);

直接使用DataTable的Select方法查询数据,返回DataRow数组,如果你并不想要得到DataRow数组,此时你不得不遍历该数组重新组装成其它对象。

这个效率也许没有使用Linq的效率高,既然这样那就直接使用Lamda表达式吧!

代码:

dt.AsEnumerable().Where(t => t.Field<decimal>("unit_id") == unitID).Select(t => t.Field<decimal>("user_id")).ToList();

返回List<decimal>对象;

注:你需要using System.Linq;和在解决方案中引用System.Data.DataSetExtensions(不需要在代码中using)。

当然如果你要使用Linq,代码如下:

(from t in dt.AsEnumerable()where t.Field<decimal>("unit_id") == unitIDselect t.Field<decimal>("user_id")).ToList();

返回List<decimal>对象;

3.适当的时候使用多线程

该场景实例运行时间较长,所以开启了新线程。也避免了UI线程的等待。

你可以封装一个线程执行类,最后将这个类对象存入Session,随时可以检测运行状态。

代码:

  /// <summary>  /// Asp.net线程执行类  /// </summary>  public class DocWork  {    /// <summary>    /// 构造函数    /// </summary>    /// <param name="method">执行方法</param>    public DocWork(Action method)    {      this.method = method;    }    private DateTime startTime;    /// <summary>    /// 开始时间    /// </summary>    public DateTime StartTime    {      get { return startTime; }    }    private DateTime endTime;    /// <summary>    /// 结束时间    /// </summary>    public DateTime EndTime    {      get { return endTime; }    }    private DateTime errorTime;    /// <summary>    /// 发生错误时间    /// </summary>    public DateTime ErrorTime    {      get { return errorTime; }    }    private Thread currnetThread;    /// <summary>    /// 当前线程    /// </summary>    public Thread CurrnetThread    {      get { return currnetThread; }    }    private string errorInfo;    /// <summary>    /// 错误信息    /// </summary>    public string ErrorInfo    {      get { return errorInfo; }    }    private Action method;    /// <summary>    /// 执行方法    /// </summary>    public Action Method    {      get { return method; }      set { method = value; }    }    /// <summary>    /// 开始执行    /// </summary>    public void Start()    {      if (currnetThread == null || currnetThread.ThreadState == ThreadState.Stopped)      {        currnetThread = new Thread(new ThreadStart(WorkMethod));        currnetThread.Start();      }    }    /// <summary>    /// 挂起线程    /// </summary>    public void Suspend()    {      if (currnetThread != null && currnetThread.ThreadState == ThreadState.Running)      {        currnetThread.Suspend();      }    }    /// <summary>    /// 继续执行挂起线程    /// </summary>    public void Resume()    {      if (currnetThread != null && currnetThread.ThreadState == ThreadState.Suspended)      {        currnetThread.Resume();      }    }    /// <summary>    /// 终止执行    /// </summary>    public void Abort()    {      if (currnetThread != null)      {        currnetThread.Abort();      }    }    /// <summary>    /// 线程方法    /// </summary>    protected void WorkMethod()    {      if (Method != null)      {        try        {          startTime = DateTime.Now;          Method.Invoke();        }        catch (Exception ex)        {          errorTime = DateTime.Now;          errorInfo = ex.Message + "|" + ex.Source;        }        finally        {          endTime = DateTime.Now;        }      }    }  }

数据访问优化的方法很多,且针对不同的环节方法也不同,本文演示的是数据库数据查询到页面处理环节。

 本文地址:.Net频繁访问数据库的优化探究 转载请标明出处