How does the Dbcontext startup work in the Entity Framework Core?

Asked

Viewed 30 times

1

How to initialize an object DbContext works? The ways I always see is by injection of dependency or using the using.

  • What would happen if I initialized it as a normal object? (Follow an example below)
  • What differs between these ways of initialization?
  • In which scenarios each is recommended?

Example of normal initialization I quoted:

public class CharacterUserWonderfulActivityUtil
{
    public CharacterUserWonderfulActivityUtil(GamePlayer player)
    {
        Player = player;
        GameDbContext = new GameDbContext();
    }

    private GameDbContext GameDbContext { get; }

    private GamePlayer Player { get; }

    public IList<CharacterUserWonderfulActivity> Activities { get; private set; }

    public IList<CharacterUserWonderfulActivityCondition> Conditions { get; private set; }

    public void Load()
    {
        Activities =
            GameDbContext.CharacterUserWonderfulActivities
                .Where(e => e.CharacterUserId == Player.Character.ID)
                .ToList();

        Conditions =
            GameDbContext.CharacterUserWonderfulActivityConditions
                .Where(e => e.CharacterUserId == Player.Character.ID)
                .ToList();
    }

    public void Save() => GameDbContext.SaveChanges();

    public void AddCondition(CharacterUserWonderfulActivityCondition condition)
    {
        Conditions.Add(condition);

        GameDbContext.CharacterUserWonderfulActivityConditions.Add(condition);
    }
}

1 answer

1


From a general point of view this is wrong, but pay attention because now I will talk about what is common to do, then I explain that the DbContext is special.

Every class that implements IDisposable should call the Dispose() somehow. The using is the most obvious form within methods. When it is part of an object, regardless of how it was placed there (Dependency Injection does not solve the problem by itself), this object needs to implement IDisposable and something needs to call Dispose() of this somewhere (some frameworks could do that for you). In Dispose() of your class needs to call the Dispose() of DbContext or other classes that implement IDdisposable, I mean, he’s viral.

When you don’t call the Dispose() the object is dropped there until the Garbage Collector call the method for you. Is this the end of the world? For certain objects not, and as far as I know the DbContext is not tragic. But it is not the ideal form, it is consuming resources without need. I can’t tell if there would be any problem in some concurrent code, but I believe not, from what I’ve seen around.

If what you use calls this code and dies shortly after, that is, it is an ephemeral execution, typical of script, then it really won’t cause any trouble, even if it’s not ideal. But if it’s something that’s been running for a long time, it may be that at some point it might have some memory problem.

How most of the time it works people think it’s right.

I should roughly create something like this:

protected IDbContext GameDbContext {get;}
protected virtual void Dispose(bool disposing) {
    if (!disposedValue) {
        if (disposing) GameDbContext.Dispose();
        disposedValue = true;
    }
}
public void Dispose => Dispose(true);

I put in the Github for future reference.

The specific recommendation for the DbContext is that it be used only within methods, so if you do so you need not worry about it. If not, you should be able to explain why you are avoiding doing what is recommended. If you do not know, do not.

The DbContext manages its resource (the connection to the database) on its own, so what is most important to do as soon as it finishes its use it already resolves, so letting the object loose is not a big problem. So every access you make opens and closes the connection for you. If he has this behavior, why do you think it’s so important to keep the object in the class instead of just creating it the moment you use it?

In fact there are those who recommend not even use the using with DbContext. And if you shouldn’t be in something so specific, in class you shouldn’t discard the object either. I don’t particularly like to treat certain objects with certain characteristics as exceptions, but it makes some sense. Maybe the DbContext nor should it have implemented IDisposable (I understand why it was).

In fact when using Dependency Injection it is common that the object is not even discarded (it depends on how you use DI). And it is not the end of the world.

I can understand the motivation to use it like this and I don’t think you’ll have any problems. But it’s not wrong to do the right thing :) I just wouldn’t know what’s more efficient (although that doesn’t change much).

I have also seen who speaks the opposite of all this, I will not confirm, nor deny, take your own conclusions reading the article. Remember that this is a different position even than the Entity Framework team recommends. But it makes some sense.

Browser other questions tagged

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