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?
CodePudding user response:
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
};
CodePudding user response:
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.