我最近开始使用 Blazor 和实体框架,遇到了一个我不知道如何正确解决的问题:
我使用 Blazor 服务器 + Web 程序集和代码优先方法用于数据库。 我有 2 个实体,与一对多的关系,并希望加载包含父对象的子对象。如果我获取表的所有子对象,则一切都很好;但是,如果我通过将 Where 方法与 Include 一起使用只得到一个孩子,应用程序将启动递归。它得到父级,然后是它的所有子项,它们的所有父项等等,直到我在客户端应用程序中得到"内存不足"异常。
我打开了Newtonsoft.Json.ReferenceLoopHandling.Ignore,它帮助我查看表格,但它不适用于仅加载一个子项。
父对象:
public partial class Project
{
public long ProjectId { get; set; }
public string Name { get; set; }
public ICollection<Environment> Environments { get; set; }
}
父接入层:
public IEnumerable<Project> GetAllProjects()
{
try
{
return _context.Projects.ToList();
}
catch
{
return new List<Project>();
}
}
public Project GetProjectData(long id)
{
try
{
Project project = _context.Projects.Find(id);
return project;
}
catch { throw; }
}
子对象:
public partial class Environment
{
public long EnvironmentId { get; set; }
public string Name { get; set; }
public long ProjectId { get; set; }
public Project Project { get; set; }
}
子访问层:
public IEnumerable<Environment> GetAllEnvironments() // this one works fine
{
try
{
return _context.Environments
.Include(e => e.Project)
.ToList();
}
catch
{
return new List<Environment>();
}
}
public Environment GetEnvironmentData(long id) // this one starts endless recursion
{
try
{
Environment env = _context.Environments
.Where(e => e.EnvironmentId == id)
.Include(e => e.Project)
.FirstOrDefault();
return env;
}
catch { throw; }
}
现在我正在手动加载父对象,但最好弄清楚如何使用 Include 自动执行此操作。
想想您希望 JSON 看起来像什么,您会发现您需要通过抑制其中一个导航属性的序列化来打破 JSON 序列化程序中的循环,可能Environment.Project
。
看起来解决方案非常简单,我没有检查"环境"对象的"项目"属性为 null。在我将此检查添加到页面后,问题就消失了。
我仍然不确定为什么页面在遇到"对象引用未设置为对象的实例"错误后消耗大量内存。
@if (env == null || env.Project == null)
{
<strong>Loading...</strong>
}
else
{
// page markup
}