繁体   English   中英

实体框架 - 对选定条目的嵌套 Select 查询

[英]Entity Framework - Nested Select Query on Selected Entry

我正在使用Entity Framework Core 3.1.4 我的 Model 就像-

public class Review
{
    [Key, Required]
    public Guid Id { get; set; }

    public int Rating { get; set; }
    public DateTime WatchDate { get; set; }

    public virtual Guid UserId { get; set; }
    public virtual User User { get; set; }
}

我的 controller 是这样的——

public async Task<IActionResult> Index()
{
    var data = await _context.Reviews
                        .Include(r=>r.User)
                        .Select(r => new Review {
                            Id = r.Id,
                            WatchDate = r.WatchDate,
                            User = r.User,
                            Rating = r.Rating
                        })
                        .OrderByDescending(r => r.Rating)
                        .ToListAsync();
    return View(data);
}

它做得很好,但它正在像这样查询User表的所有数据(红色标记区域) -

在此处输入图像描述

但我只需要email ,所以我喜欢 select 从那里只 email (黄色标记一个)。 我在上层做Select ,但不能在内部元素做同样的事情。 据我所知, Entity Framework中有这样的方法。 但是随着版本的变化,代码不起作用。

谁能帮忙,我该如何完成?

如何在列表中仅包含用户 email,而不是所有数据? 那么我怎样才能 select 嵌套条目呢?

接下来试试:

var data = await _context.Reviews
                    .OrderByDescending(r => r.Rating)
                    .Select(r => new Review {
                        Id = r.Id,
                        WatchDate = r.WatchDate,
                        User = new User { Email = r.User.Email},
                        Rating = r.Rating
                    })                       
                    .ToListAsync();

但我想说更好的设计是创建特定的DTO ,它只包含所需的属性并将其填充到Select子句中。

此外.Include(r=>r.User)调用,因为您有Select子句。

您需要 map 您的实体在具有完全相同字段的 dto(数据传输对象)中,少用户,您只添加作为参数的用户电子邮件

public async Task<IActionResult> Index()
{
    var data = await _context.Reviews
                        .Include(r=>r.User)
                        .Select(r => new Dtos.Review {
                            Id = r.Id,
                            WatchDate = r.WatchDate,
                            UserEmail = r.User.Email,
                            Rating = r.Rating
                        })
                        .OrderByDescending(r => r.Rating)
                        .ToListAsync();
    return View(data);
}

因此,来自Context评论具有类型Review Entity ,但来自您的查询的新评论具有类型Dto (两者具有相同的参数,较少的用户)

无论如何,最佳实践是不要将实体直接发送给客户端,并将 map 发送到 dto。

实体:

public class Review {
  public int Id {get; set;}
  public DateTime WatchDate {get; set;}
  public int UserId {get; set;}
  public User User {get; set;}
  public decimal Rating {get; set;}
}

Dto:

public class Review {
  public int Id {get; set;}
  public DateTime WatchDate {get; set;}
  public string UserEmail {get; set;}
  public decimal Rating {get; set;}
}

ViewModel用于视图总是更好。 所以首先,制作一个ViewModel class 如下:

public class ReviewViewModel
{
    public Guid Id { get; set; }

    public int Rating { get; set; }
    public DateTime WatchDate { get; set; }

    public Guid UserId { get; set; }
    public string UserEmail { get; set; }
}

然后将您的查询投影到ViewModel类型,如下所示:

public async Task<IActionResult> Index()
{
    var data = await _context.Reviews
                        .Select(r => new ReviewViewModel {
                            Id = r.Id,
                            WatchDate = r.WatchDate,
                            Rating = r.Rating,
                            UserId = r.User.Id,
                            UserEmail = r.User.Email,
                        })
                        .OrderByDescending(r => r.Rating)
                        .ToListAsync();
    return View(data);
}

作为最佳实践,我建议创建一个 DTO ,它只包含必要的数据而不是数据库对象:

public class UserReviewDTO
{
    public Guid Id { get; set; }
    public int Rating { get; set; }
    public DateTime WatchDate { get; set; }
    public string UserEmail { get; set; }
}

您可以像这样进行查询:

var data = await _context.Reviews
    .Select(r => new UserReviewDTO {
        Id = r.Id,
        WatchDate = r.WatchDate,
        UserEmail = r.User.Email,
        Rating = r.Rating
    })
    .OrderByDescending(r => r.Rating)
    .ToListAsync();

暂无
暂无

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

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