Linq Error A second operation started on this context before a previous operation completed

asp.net-core-mvc entity-framework-core linq

Question


I would like to build a sql query library. But unfortunately the queries do not work in subqueries. Here is the error message:
A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext, however instance members are not guaranteed to be thread safe. This could also be caused by a nested query being evaluated on the client, if this is the case rewrite the query avoiding nested invocations.

And here the code:

public class HomeController : Controller
{
    private readonly TestContext _db;

    public HomeController(TestContext db)
    {
        _db = db;
    }

    public List<Test2> GetTest2Data(int id)
    {
        return (from t2 in _db.Test2
                where t2.Id == id
                select t2).ToList();
    }

    public List<TestModel> GetTest1Data()
    {
        return (from t1 in _db.Test1
                select new TestModel
                {
                    Id = t1.Id,
                    Text = t1.Test,
                    ListTest2 = GetTest2Data(t1.Id)
                }).ToList();
    }

    public IActionResult Index()
    {
        var test = GetTest1Data();
        return View();
    }   
}

How can i fix that ?
This code works but is not resuable:

public class HomeController : Controller
{
    private readonly TestContext _db;

    public HomeController(TestContext db)
    {
        _db = db;
    }

    public List<TestModel> GetTest1Data()
    {
        return (from t1 in _db.Test1
                select new TestModel
                {
                    Id = t1.Id,
                    Text = t1.Test,
                    ListTest2 = (from t2 in _db.Test2
                                 where t2.Id == t1.Id
                                 select t2).ToList();
                }).ToList();
    }

    public IActionResult Index()
    {
        var test = GetTest1Data();
        return View();
    }   
}

Models:

public class Test1
{
    public int Id { get; set; }
    [StringLength(50)]
    public string Test { get; set; }
    public int? First { get; set; }
    public int? Second { get; set; }
}
public class Test2
{
    public int Id { get; set; }        
    [StringLength(50)]
    public string Test2 { get; set; }
    public int? First { get; set; }
    public int? Second { get; set; }
}
public class TestModel
{
    public int Id { get; set; }
    public string Text { get; set; }
    public List<Test2> ListTest2 { get; set; }
}

#Update 1

public List<TestModel> GetTest1Data()
{
    return (from t1 in _db.Test1
        select new TestModel
        {
            Id = t1.Id,
            Text = t1.Test
        }).ToList()
        .Select(t1 => {
            t1.ListTest2 = GetTest2Data(t1.Id);
            return t1;
        }).ToList();
}
1
0
8/11/2019 8:08:39 AM

Accepted Answer

There is more than one suggestion to be made, but to keep things simple as a quick fix to your problem, you can simply change where you are retrieving the data using the ToList() against the context.

public List<TestModel> GetTest1Data()
{
    return (from t1 in _db.Test1)
           .ToList()
           .Select(t => new TestModel
            {
                Id = t1.Id,
                Text = t1.Test,
                ListTest2 = GetTest2Data(t1.Id)
            }).ToList();
}

This basically will retrieve the data, completing the first operation and then call Test2Data separately so you're not executing concurrent operations on your context. That said, keep in mind it will call Test2Data on each Test1 record. It's only a test after all :)

HTH

0
8/9/2019 8:08:15 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow