[英]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.