2009-02-12 27 views
9

Ý tưởng là tạo một lớp hiển thị ngữ cảnh nhưng xử lý việc lưu trữ nó trong một ứng dụng web.Khuôn khổ thực thể: Đối tượng SingletonishContext - Tốt, Xấu, hoặc Nghĩ quá mức?

Hiện nay đây là những gì tôi có:

public class EntityContext 
{ 

    private static String MAIN_CONTEXT_KEY = "MainContext"; 
    private static TISQLEntities _context; 

    public static void RemoveContext() 
    { 
     if (
      HttpContext.Current != null 
      && 
      HttpContext.Current.Items[MAIN_CONTEXT_KEY] != null 
      ) 
     { 
      ((TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY]).Dispose(); 
      HttpContext.Current.Items[MAIN_CONTEXT_KEY] = null; 
     } 

     if (_context != null) 
     { 
      _context.Dispose(); 
      _context = null; 
     } 
    } 

    public static TISQLEntities Context 
    { 
     get 
     { 
      if (HttpContext.Current == null) 
      { 
       if (_context == null) 
       { 
        _context = new TISQLEntities(); 
       } 

       return _context; 
      } 

      if (HttpContext.Current.Items[MAIN_CONTEXT_KEY] == null) 
      { 
       HttpContext.Current.Items[MAIN_CONTEXT_KEY] = new TISQLEntities(); 
      } 

      return (TISQLEntities)HttpContext.Current.Items[MAIN_CONTEXT_KEY]; 
     } 
    } 
} 

Và sau đó trong file Global.asax:

protected void Application_EndRequest(object sender, EventArgs e) 
{ 
    EntityContext.RemoveContext(); 
} 

Ý tưởng là nếu điều này đang được chạy với một ứng dụng web, bối cảnh được tạo trên nhu cầu đầu tiên (và được lưu vào HttpContext hiện tại) và bị rớt xuống bất cứ khi nào yêu cầu kết thúc.

Nếu đây là một tình huống UnitTest, nó sẽ được tạo ra khi cần thiết và được loại bỏ trong TestCleanup (Không quan trọng trong bài này nhưng chỉ muốn làm rõ đối tượng _context).

Bây giờ ý tưởng đằng sau này nằm ở cùng nhất để không phải làm điều này:

using(TISQLEntities context = new TISQLEntities()) 
{ 
    .... 
} 

Mỗi lần tôi muốn truy vấn. Tôi nhận ra điều này có thể tôi lười biếng, nhưng tôi chỉ nghĩ rằng đó là dễ dàng hơn và sạch hơn để có:

EntityContext.Context.User.Select(...) 

Và tránh "sử dụng" mà tôi cố gắng tránh cho hầu hết các trường hợp. Trên hết, tôi không tạo ra ngữ cảnh 9001 cho mỗi postback.

Bây giờ những gì tôi tò mò về là tôi suy nghĩ về điều này? Tôi có nên tiếp tục tạo ngữ cảnh cho mọi phương thức cần có không? Nói trên một bài đăng lại tôi phải:

  • Lấy người dùng từ một ID
  • Nhận một trang web từ một id
  • Thêm trang web cho người dùng (user.Site = foundSite)
  • Lưu người dùng

Điều đó có thể kéo theo ít nhất 3 ngữ cảnh. Khung thực thể có đủ thông minh để có thể tiếp tục tạo ngữ cảnh bất cứ khi nào?

Trả lời

7

Bạn đang thực hiện tương đương phiên của NHibernate theo mẫu yêu cầu, đây là cấu trúc tốt trong NHibernate. Trong khi tôi không thể nói 100% chắc chắn rằng nó có thể áp dụng cho EF thì rất có thể. Mở rộng hơn nữa trên các mô hình quản lý phiên khác là Phiên cho mỗi cuộc hội thoại kinh doanh cho phép NHibernate mở rộng giữ một phiên trong suốt thời gian của một HttpSession bằng cách ngắt kết nối và kết nối lại phiên như trái ngược với việc hủy và tạo. Nếu EF cho phép một khả năng tương tự như trái ngược với việc giữ một kết nối mở tĩnh, bạn có thể xem xét cách tôi đã triển khai mẫu đó bằng AOP trên blog của tôi thông qua tiểu sử của tôi.

+0

Tôi không biết đây là mẫu chính xác, nhưng có, tôi đã làm việc với nHibernate trước đây và đang cố gắng làm như vậy với EF. Đó là những gì tôi đang cố gắng hoàn thành. –

+0

Có một số mẫu quản lý phiên. Mẫu chính xác phổ biến nhất là phiên cho mỗi yêu cầu, phiên cho mỗi cuộc hội thoại kinh doanh là rất mới, các mô hình quản lý phiên là phiên cho mỗi ứng dụng và phiên cho mỗi cuộc gọi (không quản lý, tạo và hủy mọi phiên) –

1

Nếu bạn đang cố gắng thực hiện một cái gì đó như NHibernate không với phiên của nó, tôi nghĩ rằng nó là một ý tưởng tốt để có loại mô hình. Tôi biết chắc chắn rằng trong LinqToSql việc thực hiện đối tượng bối cảnh giống như một lớp entrypoint hoạt động như một mặt tiền. Tôi muốn nghĩ rằng LinqToEntities là tương tự. Bạn có thể có một nhà máy thực hiện để có được một datacontext để mô hình của bạn, nơi bạn có thể tái chế các datacontext. Nếu bạn đi theo cách đơn lẻ xem xét tắc nghẽn, sẵn có và trách nhiệm của đối tượng singleton.

4

Kiểm tra this blog entry cung cấp thêm chi tiết về việc tạo một singleton cho bối cảnh Entity Framework và tại sao điều này sẽ không hoạt động trong ASP.NET và đưa ra giải pháp thực hiện điều gì đó tương tự như bạn đề xuất.

Các vấn đề liên quan