question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using DbContext in nested scope

See original GitHub issue

Hi.

I created class marked with [UnitOfWork(isTransactional: true)] attribute. Then i injected IRepository<Entity> into ctor.

In method i create something like this:

var xx = repTest.GetAll().Take(1).ToList();
using (var uov = uowManager.Begin(new UnitOfWorkOptions()
                {
                    Scope = System.Transactions.TransactionScopeOption.Suppress,
                    IsTransactional = false,
                }))
                {
                    var xx = repTest.GetAll().Take(1).ToList();
                    uov.Complete();
                }

If i look into SQL profiler first request is create inside transaction (SPID: x) and second outside of transaction (SPID: y). So everything work perfect and as expected.

If i replace repository with dbcontext then second query is executed inside of transaction (same SPID). Why is that ? I have injected IDbContextProvider<TestDbContext> into ctor and then get context from provider (calling .GetDbContext method).

Please explain why ABP works like that. Is this bug ?

Thanks for advance.

Edvin

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
acjhcommented, Mar 19, 2018

From the MSDN article on The Repository Pattern:

Use the Repository pattern to achieve one or more of the following objectives:

  • You want to maximize the amount of code that can be tested with automation and to isolate the data layer to support unit testing.
  • You access the data source from many locations and want to apply centrally managed, consistent access rules and logic.
  • You want to implement and centralize a caching strategy for the data source.
  • You want to improve the code’s maintainability and readability by separating business logic from data or service access logic.
  • You want to use business entities that are strongly typed so that you can identify problems at compile time instead of at run time.
  • You want to associate a behavior with the related data. For example, you want to calculate fields or enforce complex relationships or business rules between the data elements within an entity.
  • You want to apply a domain model to simplify complex business logic.

So yes, we generally avoid using DbContext directly.

The limitation is that IRepository only has methods that use a subset of DbContext methods. In other cases, using DbContext may be necessary. That’s where Custom Repositories come in.

1reaction
acjhcommented, Mar 19, 2018

You are using the context from the outer unit of work. Try this:

public void TestMethod()
{
    var ctxTest = dbContextProvider.GetDbContext(MultiTenancySides.Tenant);
    var data1 = ctxTest.DataForSend.Take(1).ToList();
    using (var uov = uowManager.Begin(new UnitOfWorkOptions()
    {
        Scope = System.Transactions.TransactionScopeOption.Suppress,
        IsTransactional = false,
    }))
    {
        var ctxTest2 = dbContextProvider.GetDbContext(MultiTenancySides.Tenant); // Add this
        var data2 = ctxTest2.DataForSend.Take(1).ToList(); // Modify this
        uov.Complete();
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Is there a concept of scope or nested contexts within EF ...
Let's say my application's DbContest is scoped to the http request. The way I would do it normally is any method that needs...
Read more >
Managing DbContext the right way with Entity Framework 6
Once a business transaction has completed and has called the DbContext.SaveChanges() method to persist all the changes it made, it's entirely ...
Read more >
Make the DbContext Ambient with UnitOfWorkScope
I've been looking for a better way to handle the DbContext and have come up with an ambient DbContext, using a UnitOfWorkScope which...
Read more >
Using Transactions - EF Core
You can use the DbContext.Database API to begin, commit, and rollback transactions. The following example shows two SaveChanges operations ...
Read more >
Entity Framework Core - Use TransactionScope With ...
In this article: Async methods. BeginTransaction within TransactionScope. Multiple instances of DbContext (or rather DB connections).
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found