Circular references on .NET , Entity Framework and WebAPI
Imagine having a class Department( ID, Name) and Employee ( ID , Name, IDDepartment) . You want to return in the WebAPI the Departments with the Employee . It is simple to wrote this code:
[HttpGet] public IEnumerable<Department> Get([FromServices] MyTestDatabaseContext context) { var departments = context.Department.Include(iterator=>iterator.Employee).ToArray(); return departments; }
But the problem is with circular references when serializing : The Department has a list of Employees that have a Department that have a list of Employees that …
Solution 1 : Delete/Comment from the EF generated code what you do not need ( in this case , the Department reference that the Employee has)
public partial class Employee { public int Idemployee { get; set; } public string NameEmployee { get; set; } public int Iddepartment { get; set; } //public Department IddepartmentNavigation { get; set; } }
Solution 2 : Nullify the reference
[HttpGet] public IEnumerable<Department> Get([FromServices] MyTestDatabaseContext context) { var departments = context.Department.Include(iterator=>iterator.Employee).ToArray(); foreach (var dep in departments) { foreach (var emp in dep.Employee) { emp.IddepartmentNavigation = null; } } return departments; }
( maybe this should be add to the partial class of the employee ?)
Solution 3: Handle circular references in serialization
services .AddMvc() .AddJsonOptions(opt => { opt.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects; opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore; });
Solution 4: Make a read DDD design. Read https://siderite.dev/2018/08/client-models-vs-data-transfer-objects.html