首页 > 解决方案 > EF Core 5 中的一对一关系

问题描述

大家好,提前感谢任何会帮助我的人;

我正在使用 .net core 5 和 Entity Framework Core,我正在尝试为电影和电视剧平台构建一个 webapi(可以说类似于 Netflix)。

我的表之间的关系有问题;尤其是:

我需要在 Documentary 表和 Actor 表之间创建关系;

这是我的 DocumentaryController.cs 文件:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using microsquare.Services;
using microsquare.Context;
using microsquare.Models;

namespace microsquare.Controllers
{
   [EnableCors("MyPolicy")]
   [Route("api/[controller]")]
   [ApiController]
   public class DocumentaryController : ControllerBase
   {
       ApiAppContext apiContext;
       public DocumentaryController(ApiAppContext context)
       {
           apiContext = context;
           apiContext.Database.EnsureCreated();
       }
       
       
       [HttpGet]
       public ActionResult<IEnumerable<Documentary>> Get()
       {
           return apiContext.Documentaries.Where(p => p.Rated).ToList();
       }

       [HttpGet("{id}")]
       public ActionResult<string> Get(string id)
       {
           Guid.TryParse(id, out var documentaryId);
           if (documentaryId != Guid.Empty)
           {
               var documentaryFound = apiContext.Documentaries.FirstOrDefault(p => p.DocumentaryId == documentaryId);
               if (documentaryFound != null)
               {
                   return Ok(documentaryFound);
               }
               else
               {
                   return NotFound();
               }
           }
           else
           {
               return BadRequest();
           }
       }

       [HttpPost]
       public async Task Post([FromBody] Documentary value)
       {
           apiContext.Documentaries.Add(value);
           await apiContext.SaveChangesAsync();
       }

       [HttpPut("{id}")]
       public void Put(string id, [FromBody] Documentary value)
       {
           Guid.TryParse(id, out var documentaryId);
           if (documentaryId != Guid.Empty)
           {
               var documentaryFound = apiContext.Documentaries.FirstOrDefault(p => p.DocumentaryId == documentaryId);

               if (documentaryFound != null)
               {
                   documentaryFound.Title = value.Title;
                   documentaryFound.OriginalTitle = value.OriginalTitle;
                   documentaryFound.GenreCategory = value.GenreCategory;
                   documentaryFound.Cast = value.Cast;
                   documentaryFound.Year = value.Year;
                   documentaryFound.BelongsToCollection = value.BelongsToCollection;
                   documentaryFound.Duration = value.Duration;
                   documentaryFound.Language = value.Language;
                   documentaryFound.OriginalLanguage = value.OriginalLanguage;
                   documentaryFound.SoundTrack = value.SoundTrack;
                   documentaryFound.SoundtrackAuthor = value.SoundtrackAuthor;
                   documentaryFound.MusicAuthor = value.MusicAuthor;
                   documentaryFound.ViewsAndDownloads = value.ViewsAndDownloads;
                   documentaryFound.PosterImage = value.PosterImage;
                   documentaryFound.Rated = value.Rated;
                   documentaryFound.Budget = value.Budget;
                   documentaryFound.Included = value.Included;
                   documentaryFound.Season = value.Season;
                   documentaryFound.Episode = value.Episode;
                   documentaryFound.IsOriginal = value.IsOriginal;
                   documentaryFound.Description = value.Description;
                   documentaryFound.Direction = value.Direction;
                   documentaryFound.ProductionHouse = value.ProductionHouse;
                   documentaryFound.ContentNotice = value.ContentNotice;
                   documentaryFound.ImdbId = value.ImdbId;
                   documentaryFound.Trailer = value.Trailer;
                   documentaryFound.VideoLink = value.VideoLink;
                   documentaryFound.ActorId = value.ActorId;
                   documentaryFound.GenreId = value.GenreId;
                   documentaryFound.ProductionId = value.ProductionId;
                   documentaryFound.VideoId = value.VideoId;
                   documentaryFound.PosterId = value.PosterId;
                   apiContext.SaveChanges();
               }
           }
       }

       [HttpDelete("{id}")]
       public async Task Delete(string id)
       {
           Guid.TryParse(id, out var documentaryId);
           if (documentaryId != Guid.Empty)
           {
               var documentaryFound = apiContext.Documentaries.FirstOrDefault(p => p.DocumentaryId == documentaryId);

               apiContext.Documentaries.Remove(documentaryFound);
               await apiContext.SaveChangesAsync();
           }
       }
           
       }
   }

这是我的 Model Documentary.cs 代替:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Numerics;
using System.Threading.Tasks;

namespace microsquare.Models
{

    public class Documentary
    {
        public Guid DocumentaryId { get; set; } = Guid.NewGuid();
        [Required]
        
        public string Title { get; set; }
        [Required]
        
        public string OriginalTitle { get; set; }
        [Required]
        
        public string GenreCategory { get; set; }
        [Required]
        
        public string Cast { get; set; }
        [Required]
        
        public string Year { get; set; }
        [Required]
        
        public string BelongsToCollection { get; set; }
        [Required]
        
        public string Duration { get; set; }
        [Required]
        
        public string Language { get; set; }
        [Required]
        
        public string OriginalLanguage { get; set; }
        [Required]
        
        public string SoundTrack { get; set; }
        [Required]
        
        public string SoundtrackAuthor { get; set; }
        [Required]
        
        public string MusicAuthor { get; set; }
        [Required]
        
        public BigInteger ViewsAndDownloads { get; set; }
        [Required]
        
        public string PosterImage { get; set; }
        [Required]
        
        public bool Rated { get; set; } = false;
        [Required]
        
        public double Budget { get; set; }
        [Required]
        
        public bool Included { get; set; } = true;
        [Required]
        
        public string Season { get; set; }
        [Required]
        
        public string Episode { get; set; }

        public bool IsOriginal { get; set; } = false;
        [Required]
        
        public string Description { get; set; }
        [Required]
        
        public string Direction { get; set; }
        [Required]
        
        public string ProductionHouse { get; set; }
        [Required]
        
        public string ContentNotice { get; set; }
        [Required]
        
        public int ImdbId { get; set; }
        [Required]
        
        public string Trailer { get; set; }
        [Required]
        
        public string VideoLink { get; set; }
        [Required]

        public Guid ActorId { get; set; }
        [Required]
        
        public Guid GenreId { get; set; }
        [Required]
        
        public Guid ProductionId { get; set; }
        [Required]
        
        public Guid VideoId { get; set; }
        [Required]
        
        public Guid PosterId { get; set; }
        [Required]
        
        public DateTime DateCreated { get; set; } = DateTime.Now;
        
        public virtual Actor Actor { get; set; }
        
        public virtual Genre Genre { get; set; }
        
        public virtual Production Production { get; set; }
        
        public virtual Video Video { get; set; }
        
        public virtual Poster Poster { get; set; }
    }
    
}

那么,这就是我的 ActorController.cs 文件:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using microsquare.Services;
using microsquare.Context;
using microsquare.Models;

namespace microsquare.Controllers
{
    [EnableCors("MyPolicy")]
    [Route("api/[controller]")]
    [ApiController]
    public class ActorController : ControllerBase
    {
        ApiAppContext apiContext;
        public ActorController(ApiAppContext context)
        {
            apiContext = context;
            apiContext.Database.EnsureCreated();
        }
        
        
        [HttpGet]
        public ActionResult<IEnumerable<Actor>> Get()
        {
            return apiContext.Actors.ToList();
        }

        [HttpGet("{id}")]
        public ActionResult<string> Get(string id)
        {
            Guid.TryParse(id, out var actorId);
            if (actorId != Guid.Empty)
            {
                var actorFound = apiContext.Actors.FirstOrDefault(p => p.ActorId == actorId);
                if (actorFound != null)
                {
                    return Ok(actorFound);
                }
                else
                {
                    return NotFound();
                }
            }
            else
            {
                return BadRequest();
            }
        }

        [HttpPost]
        public async Task Post([FromBody] Actor value)
        {
            apiContext.Actors.Add(value);
            await apiContext.SaveChangesAsync();
        }

        [HttpPut("{id}")]
        public void Put(string id, [FromBody] Actor value)
        {
            Guid.TryParse(id, out var actorId);
            if (actorId != Guid.Empty)
            {
                var actorFound = apiContext.Actors.FirstOrDefault(p => p.ActorId == actorId);

                if (actorFound != null)
                {
                    actorFound.Name = value.Name;
                    actorFound.LastName = value.LastName;
                    actorFound.Age = value.Age;
                    actorFound.OriginCountry = value.OriginCountry;
                    actorFound.Picture = value.Picture;
                    apiContext.SaveChanges();
                }
            }
        }

        [HttpDelete("{id}")]
        public async Task Delete(string id)
        {
            Guid.TryParse(id, out var actorId);
            if (actorId != Guid.Empty)
            {
                var actorFound = apiContext.Actors.FirstOrDefault(p => p.ActorId == actorId);

                apiContext.Actors.Remove(actorFound);
                await apiContext.SaveChangesAsync();
            }
        }
            
        }
    }

最后,这是我的 ApiAppContext.cs 文件(我尝试在其中建立关系并且我将只发布感兴趣的部分):

builder.Entity<Documentary>().ToTable("Documentary").HasKey(p => p.DocumentaryId);
            List<Documentary> documentaries = new List<Documentary>();
            documentaries.Add(new Documentary() { Title = "Ulisse il Piacere della scoperta – Leonardo da Vinci, genio universale", OriginalTitle = "Ulisse il Piacere della scoperta – Leonardo da Vinci, genio universale", GenreCategory = "Art, Science, History", Cast = "Alberto Angela", Year = "2019", BelongsToCollection = "Ulisse il piacere della scoperta", Duration = "130 min", Language = "Italian", OriginalLanguage = "Italian", SoundTrack = "Ulisse - il piacere della scoperta - The Original Soundtrack", SoundtrackAuthor = "Giuseppe Zambon", MusicAuthor = "Giuseppe Zambon", ViewsAndDownloads = 3610, PosterImage = "https://i.ibb.co/1LbFfK1/1576500282302-leonardo-02.jpg", Budget = 0.00, Season = "20", Episode = "3", Description = "Ulisse - Il piacere della scoperta è un programma televisivo documentaristico ideato da Piero Angela ed Alberto Angela, e condotto da quest'ultimo.", Direction = "Gabriele Cipollitti", ProductionHouse = "Rai", ContentNotice = "Ospiti speciali: Gigi Proietti, Roberto Benigni, Giorgia, Antonio Paolucci, Pinin Brambilla Barcilon", ImdbId = 10, Trailer = "https://www.youtube.com/embed/VPLKt9IiOe8", VideoLink = "https://www.youtube.com/embed/WFj5HpJRQX8", ActorId = actorsInitData[0].ActorId, GenreId = genresInitData[0].GenreId, ProductionId = productionsInitData[0].ProductionId, VideoId = videosInitData[0].VideoId, PosterId = postersInitData[0].PosterId} );

            builder.Entity<Documentary>().HasData(documentaries);
            builder.Entity<Documentary>().HasOne<Actor>("Actor");
            builder.Entity<Documentary>().HasOne<Genre>("Genre");
            builder.Entity<Documentary>().HasOne<Production>("Production");
            builder.Entity<Documentary>().HasOne<Video>("Video");
            builder.Entity<Documentary>().HasOne<Poster>("Poster");

如您所见,我还必须建立其他关系,但是由于所有这些关系的程序都相同,因此即使是其中一个也足够了(我尝试过一对一关系;这不是错的?)。此外,当我尝试使用 Postman 向我的纪录片路线发起请愿时,它给了我一条 OK 消息,但它返回一个空数组。

我再次感谢任何会帮助我的人,我为我糟糕的英语道歉。

问候

标签: c#.netasp.net-mvcentity-frameworkasp.net-core

解决方案


我们将在以下 Student 和 StudentAddress 实体之间实现一对零或一的关系。

public class Student
{
    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }
}
     
public class StudentAddress 
{
    public int StudentAddressId { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public int Zipcode { get; set; }
    public string State { get; set; }
    public string Country { get; set; }

    public virtual Student Student { get; set; }
}

这可以帮助你


推荐阅读