Does Entity Framework need Session and Httpcontext?

Asked

Viewed 158 times

0

I watched some videos about Entity and saw two different versions, in a first was something simple and direct (I believe the raw form of the Entity), where it just instantiated the context of the bank and applied the add, follows the code:

using(sampleEntities ctx = new sampleEntities()){
client clt = new client();
clt.name = txtName.Text;
clt.phone = txtPhone.Text;
ctx.Add(clt);
ctx.SaveChanges();

But another teacher in another video does something different using the layers DAL, BLL and UI, this time also adding a Session which would serve to "isolate" each user’s operation on the site, while the first version would allegedly have conflicts between the many users who would be making use of the same connection for several operations simultaneously, follows the example:

public static sample01Entities Current
{
    get
    {
           if (System.Web.HttpContext.Current.Session["SampleDbContext"] == null)
        {
            db = new sample01Entities();
            System.Web.HttpContext.Current.Session["SampleDbContext"] = db;
        }
        return db;

    }
}

And here in the Dalcity class:

    public void Add(cidade c)
{
    SampleDbContext.Current.cidade.Add(c);
    SampleDbContext.Current.SaveChanges();
    SampleDbContext.Current.ChangeTracker.Entries<cidade>();
}

The point is, it’s safe to use the first form for operations CRUD without compromising code/site/security etc? Or should I always use the second example with Session to "individualize" operations and connections?

Thank you all.

1 answer

1


The use of Session with the Entity Framework is, quite the contrary, discouraged.

1) Dbcontext implements the Unit of Work standard. This means that his goal is to help you include and load your entities, modify them, and then finally send all these commands to your base. Classes that have this type of behavior are not meant to have a long life cycle in this way, in which the object is created as static once and used for all other requests.

2) It is normal for sessions to be created and destroyed throughout their requisitions and for their application to be recycled from time to time. In both cases, using a session static object can bring some unexpected scenarios, such as loss of information and invalid states of your Context object.

3) Even if you do not fall into a scenario like the above, we fall into the problem of the long life cycle. The Context object stores in its own cache all information that is queried/modified over time (it has no Garbage Collector of its own), which means you end up with several unnecessary objects and a gigantic potential for memory being used without need. Considering that each user would have a different context, probably much of that memory would still have duplicated information among themselves. If we are talking about a Session Inproc scenario it would be even worse, as all this allocated memory would still harm your web server’s ability to respond to more requests.

4) Dbcontext is not Thread-safe. This means that it is not made to have its use shared by multiple simultaneous requests, as you run the risk of falling in cases of racing conditions, among other issues that may throw you into invalid states or make use of outdated or different information than desired.

Creating new instances of contexts is not such a time-consuming or expensive activity to process. In web applications, it is common to use an instance by request or by specific operation.

There are several articles on the Internet explaining how to use context by request through dependency injection containers (Ninject, Unity, Simpleinjector, etc.). But if you don’t want to use them, you can try to keep them inside the Httpcontext object:

public static class RequestContext
{
    public static sampleEntities Current
    {
        get
        {
            if (!HttpContext.Current.Items.Contains("EFContext"))
            {
                HttpContext.Current.Items.Add("EFContext", new sampleEntities());
            }
            return HttpContext.Current.Items["EFContext"] as sampleEntities;
        }
    }
}

Global.asax:

protected void Application_EndRequest(object sender, EventArgs e)
{
     var context = HttpContext.Current.Items["EFContext"] as sampleEntities;
     if (context != null)
         context.Dispose();
}

Your example of use:

public void Add(cidade c)
{
    var context = RequestContext.Current;

    context.cidade.Add(c);
    context.SaveChanges();
    context.ChangeTracker.Entries<cidade>();
}

I believe that the dependency injection scenario could offer you better control, but this approach also works.

Recommends reading some articles (in English) to better understand how to use the Entity Framework context properly: Managing Dbcontext the right way with Entity Framework 6: an in-Depth guide MSDN - Working with Dbcontext

  • Thank you very much! I could absorb a lot and illuminate my way!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.