[英]Entity Framework - Nested Select Query on Selected Entry
I am using Entity Framework Core 3.1.4 .我正在使用Entity Framework Core 3.1.4 。 My Model is like-我的 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; }
}
My controller is like this-我的 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);
}
It is doing fine, but it is querying all data of the User
table like this (red marked areas)-它做得很好,但它正在像这样查询User
表的所有数据(红色标记区域) -
But I need only email
, so I like to select only email (yellow marked one) from there.但我只需要email
,所以我喜欢 select 从那里只 email (黄色标记一个)。 I am doing Select
in the upper level, but can't do the same thing in the inside element.我在上层做Select
,但不能在内部元素做同样的事情。 As far as I know, there was a way in Entity Framework like this .据我所知, Entity Framework中有这样的方法。 But the code is not working as version changed.但是随着版本的变化,代码不起作用。
Can anyone please help, how can I accomplish it?谁能帮忙,我该如何完成?
How can I include only user email in the list, not all data?如何在列表中仅包含用户 email,而不是所有数据? So how can I select nested entry?那么我怎样才能 select 嵌套条目呢?
Try next:接下来试试:
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();
But I would say better design would be to create specific DTO
which will contain only needed properties and fill it in the Select
clause.但我想说更好的设计是创建特定的DTO
,它只包含所需的属性并将其填充到Select
子句中。
Also .Include(r=>r.User)
call is not needed cause you have Select
clause.此外.Include(r=>r.User)
调用,因为您有Select
子句。
You need to map your entity in a dto (data transfer object) with exactly same fields, less User, where you add as parameter only UserEmail您需要 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);
}
So, Reviews from Context have type Review Entity , but new Review from your query have type Dto (both have same parameters, less User)因此,来自Context的评论具有类型Review Entity ,但来自您的查询的新评论具有类型Dto (两者具有相同的参数,较少的用户)
Anyway, a best practice is to not send entities directly to clients and map it into a dto.无论如何,最佳实践是不要将实体直接发送给客户端,并将 map 发送到 dto。
Entity:实体:
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: Dto:
public class Review {
public int Id {get; set;}
public DateTime WatchDate {get; set;}
public string UserEmail {get; set;}
public decimal Rating {get; set;}
}
It's always better to use ViewModel
for the view.将ViewModel
用于视图总是更好。 So First, make a ViewModel
class as follows:所以首先,制作一个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; }
}
Then project your query to the ViewModel
type as follows:然后将您的查询投影到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);
}
As a best practice , I would suggest to create a DTO , which only contains the necessary data and not the database objects:作为最佳实践,我建议创建一个 DTO ,它只包含必要的数据而不是数据库对象:
public class UserReviewDTO
{
public Guid Id { get; set; }
public int Rating { get; set; }
public DateTime WatchDate { get; set; }
public string UserEmail { get; set; }
}
You can make your query like this:您可以像这样进行查询:
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.