繁体   English   中英

如何让我的 API 生成我想要的多层 JSON 脚手架?

[英]How can I get my API to generate my desired multi-tiered JSON scaffolding?

这就是我希望我的 JSON object 的样子。 注意:下面的 JSON 包含一个“艺术品”节点,但我实际上无法生成它。 这是我试图解决的问题。

{
    "idArtist": 2,
    "artistName": "Alice Waters",
    "indexArtworks": [
        {
            "id": 2,
            "idArtist": 2,
            "idArtwork": 1,
            "artworks": [
                {
                    "idArtwork": 1,
                    "artworkTitle": "The Collaborative Artwork",
                }
            ]
        }
    ]
}

下面粘贴的是我的表结构图。 蓝色箭头表示现有的 FK。 橙色箭头表示一个不存在的 FK,它将是一个循环引用。 Based on my current knowledge of how the .NET Core Web API JSON scaffolding is generated, in order to create a JSON sub-sub-node using the _context.<Object>.Include().ThenInclude() API, I would need to define橙色箭头 FK。 但这会在数据库中引入循环引用,而我创建此 FK 的尝试导致了错误。

这是我的表结构,包括 FK:

CREATE TABLE [dbo].[Artists](
    [ID_Artist] [int] NOT NULL,
    [Artist_Name] [nvarchar](255) NULL,
 CONSTRAINT [PK_Artists] PRIMARY KEY CLUSTERED 
(
    [ID_Artist] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

--------------------------------------------------------------------------------------------------------------------------------------------

CREATE TABLE [dbo].[Artworks](
    [ID_Artwork] [int] NOT NULL,
    [Artwork_Title] [nvarchar](255) NULL
 CONSTRAINT [PK_Artworks] PRIMARY KEY CLUSTERED 
(
    [ID_Artwork] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

--------------------------------------------------------------------------------------------------------------------------------------------

CREATE TABLE [dbo].[Index_Artworks](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ID_Artwork] [int] NOT NULL,
    [ID_Artist] [int] NOT NULL
 CONSTRAINT [PK_Index_Artworks] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Index_Artworks]  WITH CHECK ADD  CONSTRAINT [FK__Index_Art__ID_Ar__1C1305F7] FOREIGN KEY([ID_Artwork])
REFERENCES [dbo].[Artworks] ([ID_Artwork])
GO

ALTER TABLE [dbo].[Index_Artworks] CHECK CONSTRAINT [FK__Index_Art__ID_Ar__1C1305F7]
GO

ALTER TABLE [dbo].[Index_Artworks]  WITH CHECK ADD  CONSTRAINT [FK__Index_Art__ID_Ar__1D072A30] FOREIGN KEY([ID_Artist])
REFERENCES [dbo].[Artists] ([ID_Artist])
GO

ALTER TABLE [dbo].[Index_Artworks] CHECK CONSTRAINT [FK__Index_Art__ID_Ar__1D072A30]
GO

这是我在 Web API 中的艺术家 object。

    public partial class Artists
    {
        public Artists()
        {
            IndexArtworks = new HashSet<IndexArtworks>();
        }

        public int Id { get; set; }
        public string ArtistName { get; set; }

        public virtual ICollection<IndexArtworks> IndexArtworks { get; set; }
    }

这是我在 Web API 中发出 HttpGet 的地方。 我已经指出了下面的无效行。 我意识到这是因为艺术家 object 没有橙色 FK。

        // GET: api/Artists/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Artists>> GetArtists(int id)
        {
            var artists = await _context.Artists
                .Include(i => i.IndexArtworks)
                    .ThenInclude(i => i.Artworks) // <----------- this is not valid.
                .Where(i => i.Id == id)
                .FirstOrDefaultAsync();

            if (artists == null)
            {
                return NotFound();
            }

            return artists;
        }

My question: What do I need to change in the the API request, the Artist object in the API, or the tables and their relationships in order to include the "artworks" sub-sub node in the JSON?

编辑 ------------------------------------------

@Guru Stron:不确定我是否理解您的建议-如果我错了,请纠正我。 Index_ArtworksArtworks之间的 FK 点从Index_ArtworksArtworks 我需要创建一个指向相反方向的 FK,但数据库不允许它(而且它是一个循环引用,所以它是糟糕的设计)。

如果您的建议不涉及创建橙色箭头 FK,我在 API 层中对我的IndexArtworks object 进行了以下更新:我添加了对Artworks的 HashSet 引用并添加了virtual ICollection<Artworks> 当我在 ArtistController 中取消注释.ThenInclude(i => i.Artworks)并运行 API 时,它给了我以下错误: SqlException: Invalid column name 'IndexArtworksId'. Invalid column name 'IndexArtworksId'. SqlException: Invalid column name 'IndexArtworksId'. Invalid column name 'IndexArtworksId'. 我不知道这是怎么回事,因为我在解决方案中搜索了IndexArtworksId并找不到它。

public partial class IndexArtworks
    {
        public IndexArtworks()
        {
            Artworks = new HashSet<Artworks>();
        }

        public int Id { get; set; }
        public int IdArtwork { get; set; }
        public int IdArtist { get; set; }
        public bool AVisibleYn { get; set; }
        public string AVisibleIdAdmin { get; set; }

        public virtual Artists IdArtistNavigation { get; set; }
        public virtual Artworks IdArtworkNavigation { get; set; }
        public virtual ICollection<Artworks> Artworks { get; set; }
    }

您不需要橙色关系即可使用ThenInclude 您已经拥有从IndexArtworksArtworks的 FK,所以这应该没问题:

class IndexArtworks
{
    public int ID { get; set; }
    public int ID_Artist { get; set; }
    public int ID_Artwork { get; set; }
    [ForeignKey("ID_Artist")]
    public virtual Artists Artist { get; set; }
    [ForeignKey("ID_Artwork")]
    public virtual Artworks Artwork { get; set; }
}

并查询:

 var artists = await _context.Artists
            .Include(i => i.IndexArtworks)
                .ThenInclude(i => i.Artwork) 
            .Where(i => i.Id == id)
            .FirstOrDefaultAsync();

UPD

根据您的命名约定,这应该如下所示:

public partial class IndexArtworks
{
    public int Id { get; set; }
    public int IdArtwork { get; set; }
    public int IdArtist { get; set; }
    public bool AVisibleYn { get; set; }
    public string AVisibleIdAdmin { get; set; }

    public virtual Artists IdArtistNavigation { get; set; }
    public virtual Artworks IdArtworkNavigation { get; set; }
}

并查询:

 var artists = await _context.Artists
            .Include(i => i.IndexArtworks)
                .ThenInclude(i => i.IdArtworkNavigation) 
            .Where(i => i.Id == id)
            .FirstOrDefaultAsync();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM