我需要返回完整的 json 对象(包括子 json 对象),但是我收到错误...该实体是从数据库导入的。
错误
Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.PhoneNumber_C240BC86FA502D917EFDFC445D42023BBD311F87B9B79339114CAC180EEC83F1'. Path '[0].UserProfile.PhoneNumbers[0].PhoneNumberType.PhoneNumbers'.
实体
[Table("UserProfile")]
public partial class UserProfile
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public UserProfile()
{
PhoneNumbers = new HashSet<PhoneNumber>();
Users = new HashSet<User>();
UserEmails = new HashSet<UserEmail>();
}
public int Id { get; set; }
[Column(TypeName = "datetime2")]
public DateTime? dte_modified { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<User> Users { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<UserEmail> UserEmails { get; set; }
}
API Controller
[HttpGet]
[Route("")]
public IHttpActionResult Get()
{
var result = _repository.GetAllUsers();
return Json(result);
}
存储库
public IEnumerable<User> GetAllUsers()
{
return _context.Users.ToList();
}
最佳答案
您的问题是由 Entity Framework 的一项名为 Lazy Loading 的功能引起的,默认情况下启用,并且抛出该异常是因为您的 json 序列化程序正在尝试访问 User
实例上的每个属性。属性访问触发延迟加载,因此更多实体被序列化。在这些实体上访问属性,甚至加载更多实体,并且根据您的情况,这可能会结束尝试序列化自引用循环,这是由您的 json 序列化程序检测到的。
如果你只想加载 User
实体的标量属性,你可以在你的上下文中禁用延迟加载:
public class YourContext : DbContext
{
public YourContext()
{
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ProxyCreationEnabled = false;
}
}
如果您想加载相关实体作为查询的一部分,您可以使用 Include 扩展方法:
public IEnumerable<User> GetAllUsers()
{
return _context.Users.Include(u=>u.Users).Include(u=>u.UserEmails).ToList();
}
另一种解决方案是,正如@DOTang 所建议的那样,创建一个 DTO类以仅投影您需要在 View 中显示的数据。
更新:
现在我找到了一个优秀的reference解释解决这个问题的几种方法。
关于c# - EF 6 代码首先将 IEnumerable<> 转换为 Json "Self referencing loop detected with type...",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35445318/