【问题标题】:How do I go from an EF Core navigation property to a nested Web API JSON response?如何从 EF Core 导航属性转到嵌套的 Web API JSON 响应?
【发布时间】:2018-10-22 19:42:20
【问题描述】:

我一直在尝试学习一些基本的 .Net 核心教程,我想创建一个使用 EF Core 的 Asp.net Core Web API。

基本上 .Include() 似乎什么都不做,老实说,我什至不认为一开始这是一个必要的调用。

我有一个 API,它的金鱼有想法,JSON 可以很好地返回到单独的对象,除了我的导航属性在金鱼上始终为 NULL:

[
{
    "id": 1,
    "name": "Bob",
    "isAlive": true,
    "food": 50,
    "ideas": null
},..

这是 Goldfish 类(它也不适用于 ICollection)

 public class Goldfish
{
    public long ID { get; set; }
    public string Name { get; set; }
    public bool IsAlive { get; set; }
    public long Food { get; set; }

    public IEnumerable<Idea> Ideas { get; set; }
}

这里是 Idea 类(我绝望地使用外键属性使其工作,以前我有一个 GoldfishID 属性。

    public class Idea
{
    public long ID { get; set; }
    public string Title { get; set; }
    public string Gist { get; set; }
    public long GoldfishID { get; set; }

    [ForeignKey("GoldfishID")]
    public Goldfish Goldfish { get; set; }

}

我认为我的数据库没问题,因为我的 Idea 表上已经设置了外键:

ALTER TABLE [dbo].[Ideas]  WITH CHECK ADD  CONSTRAINT 
[FK_Ideas_Goldfish_GoldfishID] FOREIGN KEY([GoldfishID])
REFERENCES [dbo].[Goldfish] ([ID])
ON DELETE CASCADE
GO

但是当我访问我的控制器方法时:

        [HttpGet]
    public IEnumerable<Goldfish> GetAll()
    {
        var stuff = _context.Goldfish.Include(i => i.Ideas);

        return stuff.ToList();
       // return _context.Goldfish.ToList();
    }

多亏了我在全世界最喜欢的工具,我知道运行的 SQL 没有连接,也没有任何获取想法的尝试——我的金鱼脑死了 :(

    SELECT [g].[ID], [g].[Food], [g].[IsAlive], [g].[Name]
FROM [Goldfish] AS [g]

请让我知道我哪里出错了...我的返回类型不包括我想要的结构类型吗?我会说我没有在 OnModelCreating 中明确设置所需的一对多,因为教程没有这样做,这是我的整个上下文:

    public class GoldfishContext : DbContext
{
    public GoldfishContext(DbContextOptions<GoldfishContext> options)
        : base(options)
    {
    }

    public DbSet<Goldfish> Goldfish { get; set; }
    public DbSet<Idea> Ideas { get; set; }

    //Interrupt the standard configuration of table names, the tutorial has this and it's nice to keep ffr
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Goldfish>().ToTable("Goldfish");


    }
}

我应该提一下!我在我的 DBInitialise 中添加了这些想法,它们肯定存在于数据库中:

            var pondideas = new Idea[]
        {
            new Idea {Title="Bobs idea", Gist = "Give bob food", GoldfishID=1},
            new Idea {Title="Bobs second idea", Gist = "Give bob more food", GoldfishID=1},
            new Idea {Title="Nice idea", Gist = "Feed everyone", GoldfishID=1},
            new Idea {Title="terrible idea", Gist = "Feed nobody", GoldfishID=1}
        };

【问题讨论】:

  • 您使用的是最新版本的 EF Core 吗?
  • 啊!看起来我添加了 .Net 框架包来获取 Include() 方法,这就是问题所在,但是它现在给了我想要的东西,但只发送了部分响应!即 Postman 说没有回应,Chrome 显示了我想要的结构的开始。解决方法是添加 .AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);对于如此常见的事情,我发现它相当晦涩!谢谢!我希望这个问题对未来的我有所帮助。
  • 没有什么“晦涩难懂”的。一个库称为 JSON.NET,另一个是 EntityFramework Core。一个对另一个一无所知。启用引用也是一件好事,否则它会在第一次引用时静默停止,如果它已经存在并且用户可能想知道为什么它不完整。异常是明确的,并告诉用户问题,当他禁用它时,他很清楚这种行为
  • 因此,您也不应该从 API 返回 EF Core 模型。始终将模型转换为适合您的 WebAPI 响应的结构(即通过删除反向导航属性)

标签: .net json asp.net-core entity-framework-core asp.net-core-webapi


【解决方案1】:

已经指出了正确的方向(感谢 Shyju),我想明确地提出解决方案:

.Include() 的正确包是 Microsoft.EntityFrameworkCore

您需要添加的内容: 使用 Microsoft.EntityFrameworkCore;

代码在错误的版本(.Net 框架)下运行,但 include 不会执行任何操作。

一旦您添加了正确的库,并且如果您的模型像我的那样链接,您的 API 将超时,除非您将以下 JsonOptions 添加到您的 Startup 中以防止循环引用混乱:

            services.AddMvc()
        .AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-22
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多