Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

c# - when DbContext is garbage-collected or disposed when using in Repository?

I have implemented the Repository pattern and in the Repository, I added dbContext in the constructor as below. There are reasons for static is used. When I research it, it's not recommended to use static in the Context. I understood most of them but did not get when the context is disposed as if I make it as static, it's not disposed by garbage collector. Then when it's disposed? When a HTTP Request is finished? Or is it alive until the application is closed?

private static DBContext _context;
public OrderRepository(DbContext context)
{
    _context = context;
}

question from:https://stackoverflow.com/questions/65897688/when-dbcontext-is-garbage-collected-or-disposed-when-using-in-repository

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A static object will stay alive until the end of the program.

However, it is not the static part that you should worry about, it is the IDispose part.

Your DbContext will not be Disposed until the end of your program. Whether this is a problem or not, depends on whether others will connect to the database, and how long your program will run.

If you have a program that only runs a few seconds, then it won't be a big problem if the database connection is kept alive fore these seconds.

Be aware though, that apart from the database connection, there is also a ChangeTracker.

Whenever you query complete entities (= complete table rows), the original value and a copy of the fetched item will be put in the ChangeTracker. You get a reference to this copy. Whenever you change the values of properties of the fetched item, these changes will be in the copy that is in the ChangeTracker.

When you call SaveChanges, the copy is compared to the original to determine which property values must be updated.

If you keep your DbContext alive for quite some time, and you fetch a lot of items, then you will have a ChangeTracker filled with a lot of items.

Furthermore, if you use Find to get an item by primary key, then the DbContext will first check if the item is already in the ChangeTracker or not.

So apart from performance problems caused by the huge contents of the ChangeTracker, you will also not get the latest database value of fetched items.

If someone else updates a Customer and you fetch the same Customer, then it depends on whether you already have fetched this Customer a few hours ago or not, which Customer you get: the old non-updated Customer that you fetched before the Customer was updated, or the new updated Customer, because you haven't fetched this Customer yet? Are you sure that you want to keep track of which Customers you have fetched since you started your program? If you don't do this, you will never know whether you get the Customer that you fetched a few hours ago, or the latest updated version.

These are enough problems that can easily be mitigated by keeping your DbContext alive as short as possible. Add the argument that creating a DbContext object for a second time is fairly cheap, and I'm convinced that you shouldn't keep the DbContext object alive longer than needed.

public Customer AddCustomer(...)
{
    using (var dbContext = new MyDbContext())     // or use a factory
    {
        Customer addedCustomer =  dbContext.Customers.Add(...);
        dbContext.SaveChanges();
        return addedCustomer;
    }
}

public ICollection<Customer> QueryCustomerByCity(int CityId)
{
    using (var dbContext = new MyDbContext()) 
    {
        return dbContext.Customers
            .Where(customer => customer.CityId == cityId)
            .ToList();
    }
}

etc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...