0

I am working on an ASP.NET Core 6 Web API application with Entity Framework Core. I have entities AssetsCategoryMaster and Users. AssetsCategoryMaster has a reference navigation property for Users (CreatedBy) and Users has a collection navigation property for AssetsCategoryMaster (AssetsCategoryCreatedList).

I just query AssetsCategory as shown here:

var AssetCategoryList = await _context.Set<AssetsCategoryMaster>()
                                      .Where(p => !p.IsDeleted).ToListAsync();

I noticed by default the Users (CreatedBy) loaded with AssetCategory, and inside the CreatedBy, I can see AssetsCategoryCreatedList also loaded.

API call results in this error:

System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. Path: $.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.CreatedBy.AssetsCategoryCreatedList.AssetCategoryName.......

The related entities are loaded without use of .Include. I m not sure what I'm doing wrong.

Could anyone help me with this?

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Suresh M
  • 169
  • 1
  • 9
  • 1
    [AutoInclude](https://learn.microsoft.com/en-us/ef/core/querying/related-data/eager#model-configuration-for-auto-including-navigations)? [Lazy Loading](https://learn.microsoft.com/en-us/ef/core/querying/related-data/lazy)? – Alexander Petrov Dec 06 '22 at 16:47
  • 1
    Check if you have [`UseLazyLoadingProxies`](https://learn.microsoft.com/en-us/ef/core/querying/related-data/lazy) call on db context setup. Or [`AutoInclude`](https://learn.microsoft.com/en-us/ef/core/querying/related-data/eager#model-configuration-for-auto-including-navigations) on corresponding entities. – Guru Stron Dec 06 '22 at 16:48
  • Hi @AlexanderPetrov Thanks for your comments. No LazyLoadingProxies call on dbcontext setup. I added QueryTrackingBehavior.NoTracking in OnConfiguring the problem solved. – Suresh M Dec 07 '22 at 13:32

2 Answers2

2

You need to add the below JSON serializer option as you want to ignore those AssetsCategoryCreatedList. This will ignore the circular reference and you will not get the above error. This is the way for ignoring circular references in System.Text.Json. More information is on this page.

JsonSerializerOptions options = new()
            {
                ReferenceHandler = ReferenceHandler.IgnoreCycles            
            };
Chinmay T
  • 745
  • 1
  • 9
  • 17
1

Include is used to eagerly load navigation properties. Without it, navigation properties will be loaded lazily only if the DbContext is configured to do so, eg by calling UseLazyLoadingProxies in the DbContext's configuration. When AssetsCategoryMaster gets serialized, the serializer will try to serialize the navigation properties at which point they'll be loaded.

If lazy loading isn't needed at all, UseLazyLoadingProxies should be removed.

If lazy loading is needed for other queries, one option is to disable tracking and thus lazy loading by using AsNoTracking() :

var AssetCategoryList = await _context.Set<AssetsCategoryMaster>()
                                      .AsNoTracking()
                                      .Where(p => !p.IsDeleted)
                                      .ToListAsync();

Another option, shown in the other answer, is to ignore circular references.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • Hi @Panagiotis Kanavos Thanks for comment. As per your advise i used the below line and the issue resolved. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); } – Suresh M Dec 07 '22 at 13:45