Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy loader throwing invalid operation exceptions #32390

Closed
MoazAlkharfan opened this issue Nov 22, 2023 · 2 comments · Fixed by #32522
Closed

Lazy loader throwing invalid operation exceptions #32390

MoazAlkharfan opened this issue Nov 22, 2023 · 2 comments · Fixed by #32522
Assignees
Labels
area-dbcontext area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Milestone

Comments

@MoazAlkharfan
Copy link

MoazAlkharfan commented Nov 22, 2023

File a bug

Include your code

Assuming it's because of concurrent access to memory cached entities after they have been loaded and the DbContext has already been disposed.

Reproduction repository: https://github.com/MoazAlkharfan/efcore-issue-32390

Places to check:

  • TagsCacheService fetch data from db
  • Program mapped / endpoint
  • ServerRequest do get requests on the / endpoint

Include stack traces

For the first:

private bool IsLoading((object Entity, string NavigationName) navEntry)
=> (_isLoading ??= new List<(object Entity, string NavigationName)>())
.Contains(navEntry, EntityNavigationEqualityComparer.Instance);

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.LazyLoader.Load(Object entity, String navigationName)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()

private void DoneLoading((object Entity, string NavigationName) navEntry)
{
for (var i = 0; i < _isLoading!.Count; i++)
{
if (EntityNavigationEqualityComparer.Instance.Equals(navEntry, _isLoading[i]))
{
_isLoading.RemoveAt(i);
break;
}
}
}

For the second:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.LazyLoader.Load(Object entity, String navigationName)
   at Castle.DynamicProxy.AbstractInvocation.Proceed()

Include provider and version information

EF Core version: 8.0
Database provider: (Microsoft.EntityFrameworkCore.SqlServer)
Target framework: (.NET 8.0)
Operating system: Windows/Linux
IDE: (Visual Studio 2022 17.9)

@ajcvickers
Copy link
Member

This issue is lacking enough information for us to be able to fully understand what is happening. Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.

@MoazAlkharfan
Copy link
Author

MoazAlkharfan commented Nov 23, 2023

@ajcvickers
Reproduction repository: https://github.com/MoazAlkharfan/efcore-issue-32390

Places to check:

  • TagsCacheService fetch data from db
  • Program mapped / endpoint
  • ServerRequest do get requests on the / endpoint

@ajcvickers ajcvickers self-assigned this Dec 5, 2023
ajcvickers added a commit that referenced this issue Dec 5, 2023
Fixes #32390

Since the DbContext is not thread-safe, lazy-loading proxies cannot be used from multiple threads _when loading is happening_. However, it is a common pattern to pass proxies to other parts of the application after the navigations have been loaded. At this time, accesses should be thread-safe. We broke this in 8.
@ajcvickers ajcvickers added this to the 8.0.2 milestone Dec 5, 2023
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Dec 5, 2023
ajcvickers added a commit that referenced this issue Dec 7, 2023
Fixes #32390

Since the DbContext is not thread-safe, lazy-loading proxies cannot be used from multiple threads _when loading is happening_. However, it is a common pattern to pass proxies to other parts of the application after the navigations have been loaded. At this time, accesses should be thread-safe. We broke this in 8.
@ajcvickers ajcvickers reopened this Dec 7, 2023
ajcvickers added a commit that referenced this issue Dec 7, 2023
Fixes #32390

Since the DbContext is not thread-safe, lazy-loading proxies cannot be used from multiple threads _when loading is happening_. However, it is a common pattern to pass proxies to other parts of the application after the navigations have been loaded. At this time, accesses should be thread-safe. We broke this in 8.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dbcontext area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants