I have a service that pulls back entities using EagerLoading. For the most part this works, but I have recently found an issue. I have a field:
public class Field
{
[Required] public int Id { get; set; }
[Required, MaxLength(100)] public string CategoryId { get; set; }
[Required, MaxLength(100)] public string Name { get; set; }
public FieldDataType DataType { get; set; }
public bool IsSpecification { get; set; }
public IList<FieldMap> FieldMaps { get; set; }
}
As you can see, it has a collection of FieldMaps associated with it. The FieldMap looks like this:
public class FieldMap
{
public int Id { get; set; }
public int FeedId { get; set; }
public int FieldId { get; set; }
[Required, MaxLength(100)] public string Path { get; set; }
public Field Field { get; set; }
}
Which is mapped up in my DbContext like this:
modelBuilder.Entity<Field>().HasMany(m => m.FieldMaps).WithOne().HasForeignKey(m => m.FieldId);
// Unique constraints
modelBuilder.Entity<Field>().HasIndex(m => new { m.CategoryId, m.Name, m.IsSpecification }).IsUnique();
modelBuilder.Entity<FieldMap>().HasIndex(m => new { m.FeedId, m.Path }).IsUnique();
// Disable cascade delete
modelBuilder.Entity<FieldMap>().HasOne(m => m.Field).WithMany(m => m.FieldMaps).OnDelete(DeleteBehavior.Restrict);
The problem is, when I call the List method, it pulls back all items forever:
My list method is like this:
public IQueryable<T> List(params string[] includes)
{
IQueryable<T> query = _dbEntitySet;
return includes == null ?
query :
includes.Aggregate(query, (current, include) => current.Include(include));
}
And I invoke it like this:
[HttpGet("{id:int}/fields")]
[ProducesResponseType(typeof(List<Field>), StatusCodes.Status200OK)]
public IActionResult ListFieldMaps(int id)
{
var feeds = _feedService.List();
var feed = feeds.SingleOrDefault(m => m.Id.Equals(id));
if (feed == null) return NotFound();
var fieldMaps = _fieldMapService.List("Field");
if (fieldMaps.Any(m => m.Field == null)) return BadRequest(Resources.NullFieldError);
return Ok(fieldMaps.Where(m =>
m.FeedId.Equals(id) &&
m.Field.IsSpecification == (feed.Type == FeedType.Specification)).ToList());
}
As you can see, it should only load a list of FieldMaps with one Field, not the rest of the fieldmaps after that.
Can someone help me with this issue?
I found this article:
https://learn.microsoft.com/en-us/ef/core/querying/related-data#lazy-loading
and this issue:
https://github.com/aspnet/EntityFrameworkCore/issues/11564
and from both of them was able to add this:
services.AddMvc()
.AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
Which caused my issue to be resolved. Now when I do a request, I get this response:
[
{
"Id": 1,
"FeedId": 1,
"FieldId": 10,
"Path": "aw_product_id",
"Field": {
"Id": 10,
"CategoryId": "cameras",
"Name": "gtin",
"DataType": 0,
"IsSpecification": false,
"FieldMaps": []
}
}
]