The uniqueness and optimization of the EF context object thread, and the ef context object thread

Source: Internet
Author: User

The uniqueness and optimization of the EF context object thread, and the ef context object thread

In a request, that is, if an EF data context object is used in a thread, create one. This is also a habit of using context objects in many people's code, normally, objects are created in using to release context objects as soon as possible. However, if one business logic calls multiple methods on the dal layer and interacts with the database multiple times, this is less efficient, and when EF is used, we usually mention the SaveChange Method to the business logic layer (which will be mentioned below ), it is not guaranteed that the same business logic uses the same context object, transaction, and work unit mode will not be implemented. In addition, data may be disordered. Each time the created object executes the corresponding database operation, the same request may contain different operations on the data. Data obtained from other EF objects may have expired. That is, the data has changed. This is dirty read.

To solve this problem, the key is to create a context object.

Here we first think of the singleton mode, but it is not suitable for use here because the singleton mode will make the EF object unable to release resources in time. Imagine that the DbContext object container has added Attach monitoring on the Model object for countless requests to access the database, and the memory burst.

Optimization is the process of compromise, so the second method is to ensure that the objects in the thread are unique and use the same context for each request. How can we ensure that the HttpContext object and CallContext object related to the thread through the Microsoft ASP mechanism. As mentioned in the previous article, the HttpContext mechanism relies on CallContext objects. Let's take a look at using CallContext to solve this problem.

You can add a processing class to the Common website as follows:

 

[Csharp]View plain copy
  1. /// <Summary>
  2. /// Create the EF context object and ensure that it is unique within the thread.
  3. /// </Summary>
  4. Public class DbContextFactory
  5. {
  6. // DbContext in System. data. entity;, but it is not possible to reference only this one here, and there are some other namespaces of EF, so you can directly add an Entity model. All references come in, and then delete the model.
  7. Public static DbContext GetDbContext ()
  8. {
  9. DbContext dbContext = (DbContext) CallContext. GetData ("dbContext ");
  10. If (dbContext = null)
  11. {
  12. DbContext = new WebEntities ();
  13. CallContext. SetData ("dbContext", dbContext );
  14. }
  15. Return dbContext;
  16. }
  17. }

Is it like a Cache Usage Policy.

After a while of careful consideration, I found that the problems with using CallContext for storage are as follows? That is to say, the context object is dependent on a thread. Because of the existence of the thread pool, the thread is not destroyed after processing a request, and the context object stored in CallContext also exists, if the next time this thread is used to process another request, the context object is still expanding, but it is a little slower than the global expansion. In addition, sometimes a thread does not necessarily process requests. If the server processes other services, other problems may occur.

Therefore, to improve the above method, refer to hibernate and mybatis of J2EE, and add a remove Method in DbContextFactory. After each request in the business logic layer uses the context, remove it from the thread.

Solved, but this solution is really... If I need to call the business logic several times in one request, I still need to create multiple contexts. In addition, manual management is painful. I believe this is also the reason why we prefer HibernateTemplate instead of HibernateDaoSupport in spring + hibernate.

In fact, we still have a better way. There is an Items attribute in HttpContext, which can also be used to save the key-value. This is perfect. A request corresponds to an HttpContext and the request ends, it is automatically released, and the EF context does not exist. Change CallContext in the above Code to HttpContext. Current. Items, OK.

 

[Csharp]View plain copy
  1. Public static DbContext ()
  2. {
  3. DbContext dbContext = HttpContext. Current. Items ["dbContext"] as DbContext;
  4. If (dbContext = null)
  5. {
  6. DbContext = new WebEntities ();
  7. HttpContext. Current. Items ["dbContext"] = dbContext;
  8. }
  9. Return dbContext;
  10. }

 

 

 

Besides, the SavaChanges method can be used to optimize EF context creation. What about database interaction? This is the method we wrote countless times:

 

[Csharp]View plain copy
  1. Public int AddUser (User user)
  2. {
  3. Context. Add (user );
  4. Return context. SaveChanges ();
  5. }


When we use a complex method of business logic, it may need to use multiple dal layer objects or call methods of multiple dal layers. The preceding statement calls several times, EF interacts with the database several times, and the efficiency is still very low. Why don't we mention the database interaction method SaveChanges () to the bll layer for calling, which is called by the bll layer method. The business logic is only interacted once, form a work unit model.

 

So how to extract it is simply because our context object is unique in the request.

 

[Csharp]View plain copy
  1. Public class DbSession
  2. {
  3. Public static int SaveChanges ()
  4. {
  5. Return DbContextFactory. GetDbContext (). SaveChanges ();
  6. }
  7. }

 

 

Why should I take this class name as DbSession? A friend who learns JavaEE may immediately think of MyBatis and Hibernate. we encapsulate a unit operation on the database to interact with the database, is a session with the database.

In addition, when I first came into contact with EF, I had this question. If EF handles transactions, it would use TransactionScope or DbConnection? This is not necessary. If we mention SaveChanges () to the business logic layer, it will constitute a transaction unit. Let's look at spring, why should we put declarative transactions on the Service layer rather than the Dao layer, in addition, the SaveChanges () method is actually a feature of the transaction itself. If the uniqueness of the context object is maintained, the transaction unit is indirectly completed.

 

============================================== 2016-11-7 ================== ====================

We recently used nhib.pdf in MVC and still need to manage Session objects like EF context. Similarly, we can also "cache" It In HttpContext, however, nhib.pdf has helped us with similar work. For more information, see http://www.cnblogs.com/13yan/archive/2013/05/17/3083552.html. The author also provided a NHibernateHelper, which is awesome.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.