EF Core API 进行正确的多对多查询

问题描述 投票:0回答:1

我对 EF core 和 C# 总体来说还很陌生。 我试图了解如何从 EF core 为我制作的中间表进行正确的查询。

public class Device
{
    public Guid Id {get ; set;}
    public string Model { get; set; }
    public string Description { get; set; }
    public int  Release_Year { get; set; }
    public double RentPrice { get; set; }
    public double PurchasePrice { get; set; }
    public ICollection<Category>? DeviceCategory { get; set; } = default!;
    public Guid AppUserId { get; set; }
    public AppUser? AppUser { get; set; }
   
}

public class Category

{ 

   public Guid Id {get ; set;}
   public string Name { get; set; }
   public Guid AppUserId { get; set; }
   public AppUser? AppUser { get; set; }

}

下面我附上了迁移和创建数据库后为我制作的 ERD 和 EF 核心

所以现在我试图获取设备并从我的API控制器附加设备所属的所有类别,但我有点困惑如何做到这一点,因为我没有CategoryDevice表的数据库集。

  // GET: api/Devices/5
        [HttpGet("{id}")]
        public async Task<ActionResult<Device>> GetDevice(Guid id)
        {
            var device = await _context.Devices.FindAsync(id);
            
            if (device == null)
            {
                
                return NotFound();
            }

            return device;
        }

目前,如果我尝试发出 GET 请求,我的 deviceCategory 为空 { “型号”:“索尼相机”, “描述”:“很酷的相机”, “发布年份”:2055, “租金价格”:33.23, “购买价格”:55.3, “设备类别”:空, “appUserId”:“155f58bb-bd41-4213-9ea0-5a7fc0847ebc”, “应用程序用户”:空, “id”:“31d1d653-88ff-4f57-a05c-dfb6a9768291” },

erd

c# api linq entity-framework-core
1个回答
0
投票

默认情况下,EF core 不会从数据库中获取相关实体。如果您还想获取主要实体和相关实体,则需要要求 EF core 来执行此操作。 有多种方法和模式可以做到这一点,您可以在此处找到有关此主题的更多信息。

加载相关实体的最简单模式是急切加载方法,当您从数据库中获取主实体时,您会急切地加载相关实体。这将导致一个包含一个或多个连接的数据库查询。

在您的情况下,如果您想使用急切加载方法,可以这样做:

var device = await _context
  .Devices
  .Include(x => x.DeviceCategory)
  .FirstOrDefaultAsync(id);

这里可能的改进点是定义仅在表示层中使用的正确数据传输对象,并使用要向 API 客户端公开的最少数据量。这样,您可以避免将实体直接暴露给消费者,并且可以解耦域模型和表示层。随着时间的推移,这将使维护变得更加容易。

这是这种方法的一个例子:

public sealed class CategoryDto 
{
  public string Name { get; init; }
}

public sealed class DeviceDto 
{
  public Guid Id {get ; init;}
  public string Model { get; init; }
  public string Description { get; init; }
  public IReadOnlyList<CategoryDto> Categories { get; init; } = new List<CategoryDto>();
}

var device = await _context
  .Devices
  .Select(d => new DeviceDto 
  {
    Id = d.Id,
    Model = d.Model,
    Description = d.Description,
    Categories = d.Categories.Select(c => new CategoryDto 
    {
      Name = c.Name 
    }).ToList()
  })
  .FirstOrDefaultAsync(id);
© www.soinside.com 2019 - 2024. All rights reserved.