【发布时间】:2023-02-04 11:27:39
【问题描述】:
我正在开发一个简单的 Web API,它只是用来解析 JSON 树,并将其保存到数据库中。我正在使用 EF Core 6.0.4,我的应用程序显示了一个非常奇怪的行为:在保存树之后,它从上下文中加载得很好。但是当我调用不同的端点并使用新初始化的上下文加载数据时,子项将不会加载。我相信这是由于 EF 配置,但我不知道如何加载孩子。
我尝试使用 _context.Entity(returnValue).Collection(x => x.Children) 但 lambda 中的 x 只有 ICollection 扩展方法,而不是我看到的代码示例中的模型字段。
我也尝试使用.Include,但这似乎是来自常规 EF 的东西。
这是我的一些代码:
控制器
public class CategoryTreeManagerController : ControllerBase
{
private readonly CategoryTreeManagerService _service;
public CategoryTreeManagerController(CategoryTreeManagerService service)
{
_service = service;
}
[HttpGet]
public IEnumerable<CategoryTreeNode> GetTree()
{
return _service.GetTree(); //this only returns the root node without any children
}
[HttpPost]
public IEnumerable<CategoryTreeNode> SaveTree(CategoryTreeNode[] nodes)
{
_service.SaveTree(nodes[0]);
return _service.GetTree(); //this correctly returns the tree
}
}
服务
public class CategoryTreeManagerService
{
private readonly CategoryTreeManagerApiDbContext _context;
public CategoryTreeManagerService(CategoryTreeManagerApiDbContext context)
{
_context = context;
}
public IEnumerable<CategoryTreeNode> GetTree()
{
CategoryTreeNode[] returnValue = _context.CategoryTreeNodes
.Where(x => x.Parent == null) //just return the root node
.ToArray(); //easier for frontend
return returnValue;
}
public void SaveTree(CategoryTreeNode node)
{
if (_context.CategoryTreeNodes.Any(x => x.Id == node.Id))
{
_context.Update(node);
}
else
{
_context.CategoryTreeNodes.Add(node);
}
_context.SaveChanges();
}
}
数据库上下文
public class CategoryTreeManagerApiDbContext : DbContext
{
public CategoryTreeManagerApiDbContext() : base ()
{
Database.EnsureCreated();
}
public CategoryTreeManagerApiDbContext(DbContextOptions<CategoryTreeManagerApiDbContext> options) : base(options)
{
Database.EnsureCreated();
}
public DbSet<CategoryTreeNode> CategoryTreeNodes { get; set; }
public DbSet<TreeNodeDetail> TreeNodeDetails { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CategoryTreeNode>(entity =>
{
entity.HasKey(x => x.Id);
entity.HasOne(x => x.Parent)
.WithMany(x => x.Children)
.IsRequired(false)
.OnDelete(DeleteBehavior.Restrict);
});
}
模型类
public class CategoryTreeNode
{
public int Id { get; set; }
public string Label { get; set; }
public string Story { get; set; }
public string Icon { get; set; }
public ICollection<TreeNodeDetail> Details { get; set; }
public ICollection<CategoryTreeNode> Children { get; set; }
[JsonIgnore]
public CategoryTreeNode? Parent { get; set; }
}
public class TreeNodeDetail
{
[JsonPropertyName("detailId")]
public string Id { get; set; }
[JsonPropertyName("detailTitle")]
public string Title { get; set; }
[JsonPropertyName("detailValue")]
public string Value { get; set; }
[JsonIgnore]
[ForeignKey("CategoryTreeNode")]
public int CategoryTreeNodeId { get; set; }
}
【问题讨论】:
-
尝试以下技巧
CategoryTreeNode[] returnValue = _context.CategoryTreeNodes.ToList().Where(x => x.Parent == null).ToArray(); -
@SvyatoslavDanyliv 有用,谢谢!知道导致此问题的后台发生了什么吗?
-
这不是问题。 EF Core 无法通过
Include或其他技术一次加载整个树,但当您加载所有实体时,它可以自动修复/填充导航属性。所以在你的情况下,树被正确填充。当您尝试加载树的叶子时,这将是一个问题,您可能需要创建存储过程。
标签: entity-framework-core configuration