Answering your specific answer, just disable proxy creation just for a specific code block, but you will have to eager load your entities like so:
try
{
DbContext.Configuration.ProxyCreationEnabled = false;
var userWithRoles = DbContext.Users.Include(x => x.Roles).Where(x => x.Id == id).FirstOrDefault();
}
finally
{
DbContext.Configuration.ProxyCreationEnabled = true;
}
...which will affect only that instance. I wrapped this in a try finally block, because if any exception occur while loading entities, you can make sure that option will be reversed.
You could also set this globally inside your DbContext constructor, but I don't recommend this:
public class YourDbContext : DbContext
{
public YourDbContext() : base("name=ConnectionString")
{
this.Configuration.ProxyCreationEnabled = true;
}
}
My recommendation is to avoid exposing you database entities to an API. You can create DTO classes and expose them, instead:
// original entities
public class User {
public int Id{get; set;}
public string Name{get; set;}
public ICollection<Role> Roles{get; set;}
// other fields like birthdate, status, password, etc...
}
public class Role {
public int Id{get; set;}
public string Name{get; set;}
public virtual User User{get; set;}
}
// DTO classes, keeping only the fields you want
// original entities
public class UserDTO {
public int Id{get; set;}
public string Name{get; set;}
public ICollection<RoleDTO> Roles{get; set;}
}
public class RoleDTO {
public int Id{get; set;}
public string Name{get; set;}
}
// project them like this:
var userDTO = DbContext.Users.Where(x => x.Id == id)
.Select(u => new UserDTO
{
Id = u.Id,
Name = u.Name,
Roles = u.Roles.Select(r => new RoleDTO
{
Id = r.Id,
Name = r.Name
}),
})
.FirstOrDefault();
Then you could return just the DTO. There are tools like AutoMapper which makes easier and cleaner to project DTO classes, this is just an example.
Roleanyway.Ok(user)dont add proxy objects to json (it must be)