ASP EF框架,資料庫操作類(上下文類)的例項建立,執行緒內唯一物件(HttpContext)
阿新 • • 發佈:2019-02-13
因為多個數據庫操作類例項(上下文例項),多個例項同時操作資料庫可能會引起資料衝突,所以要用一個(同一個)操作類例項(工作單元模式,多次操作資料庫,操作多張表,但只連結一次資料庫,提高效能。(延遲載入(查詢),打上刪除、修改標記,新增操作,然後利用同一個資料庫操作類.SaveChanges()一次性儲存到資料庫,這樣就只連結了一次資料庫,提高了效能))。
如果是所有使用者都共用一個例項的話,那麼例項一直在被使用,所以就不會被釋放。如果使用者不斷操作資料庫,那麼操作類例項就會不斷的膨脹,最終撐爆記憶體。
綜上,資料庫操作類例項需要是執行緒內唯一物件(一個請求對應一個唯一物件,子執行緒中不能獲取)(利用HttpContext物件)。
未封裝版:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebApplication1 { public partial class WebForm3 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void Button1_Click(object sender, EventArgs e) { //EFFristModelEntities db = new EFFristModelEntities(); //資料庫操作類,上下文類。 EFFristModelEntities db = null; if (HttpContext.Current.Items["db"] == null) { db = new EFFristModelEntities(); HttpContext.Current.Items["db"] = db; //執行緒內唯一物件。 } else { db = HttpContext.Current.Items["db"] as EFFristModelEntities; } var userInfoList = from u in db.UserInfo where u.ID == 343 select new { UName = u.UserName, UPwd = u.UserPass }; //查詢部分列,匿名類。並不是UserInfo型別。select u;表示查詢全部列,此時userInfo是UserInfo型別。 foreach (var userInfo in userInfoList) //userInfo並不是UserInfo型別。 { Response.Write(userInfo.UName + ":" + userInfo.UPwd); } } } }
封裝版:
using XXX.Model; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Text; using System.Threading.Tasks; namespace XXX.DAL { //負責建立EF資料操作上下文例項,必須保證執行緒內唯一. public class DBContextFactory { public static DbContext CreateDbContext() { DbContext dbContext = (DbContext)CallContext.GetData("dbContext"); //CallContext就是HttpContext(執行緒內唯一物件) if (dbContext == null) { dbContext = new OAEntities(); //new XXEntities(); CallContext.SetData("dbContext", dbContext); } return dbContext; } } }