Reference to an ITVF raises a “second operation started on this context before a previous operation completed” exception

社会主义新天地 提交于 2019-12-01 21:14:53

Sorry, my fault. The technique from the answer to your previous question is applicable for calling ITVF with constant/variable parameters, but not with correlated subqueries like in your case (and my wrong example).

The solution is to remove the ITVF parameter and extend the result to include that column as well (effectively turning it into parameterless view):

CREATE FUNCTION dbo.UnitRepairStatus()
RETURNS TABLE
AS
RETURN
  SELECT u.UnitNumber, h.InRepair
  FROM    Schema2.Unit u
  INNER JOIN Schema2.History h on u.ID = h.UnitID

Also remove the parameter from the context method:

public IQueryable<UnitRepairStatus> UnitRepairStatus() =>
    Query<UnitRepairStatus>().FromSql("SELECT * FROM UnitRepairStatus()");

and change the LINQ query to use join:

var results = await (
    from v in _context.Vehicles
    join r in _context.UnitRepairStatus() on v.VehicleNumber equals r.UnitNumber // <---
    orderby v.VehicleNumber
    select new FooViewModel { 
        ID = v.ID, 
        VehicleNumber = v.VehicleNumber,
        InRepair = Convert.ToBoolean(r.InRepair)
    }
).ToListAsync();

Now it should translate and execute server side, and successfully get materialized at the client.

The problem with the original approach was that EF Core silently switched the query execution to client evaluation (hate that), and then hit its protection for executing multiple async operations on one and the same context.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!