C# 实体框架-选定条目上的嵌套选择查询
我正在使用。我的模特就像-C# 实体框架-选定条目上的嵌套选择查询,c#,asp.net,entity-framework,asp.net-core,entity-framework-core,C#,Asp.net,Entity Framework,Asp.net Core,Entity Framework Core,我正在使用。我的模特就像- 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
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; }
}
我的控制器是这样的-
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);
}
公共异步任务索引()
{
var data=wait_context.Reviews
.Include(r=>r.User)
.选择(r=>new Review{
Id=r.Id,
WatchDate=r.WatchDate,
User=r.User,
额定值=r.额定值
})
.OrderByDescending(r=>r.Rating)
.ToListAsync();
返回视图(数据);
}
它做得很好,但是它像这样查询用户
表的所有数据(红色标记区域)-
但是我只需要电子邮件
,所以我只想从中选择电子邮件(黄色标记的)。我在上层执行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
子句。请尝试下一步:
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
子句。您需要在dto(数据传输对象)中映射您的实体,该dto具有完全相同的字段,更少的用户,其中您仅添加为参数的UserEmail
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);
}
Dto:
您需要将实体映射到dto(数据传输对象)中,该dto具有完全相同的字段,更少的用户,其中您添加为仅参数的UserEmail
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);
}
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();
作为一个例子,我建议,它只包含必要的数据,而不包含数据库对象:
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();
对于视图,最好使用
ViewModel
。因此,首先,创建一个ViewModel
类,如下所示:
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; }
}
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);
}
然后将查询投影到ViewModel
类型,如下所示:
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; }
}
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);
}
公共异步任务索引()
{
var data=wait_context.Reviews
.选择(r=>new ReviewViewModel{
Id=r.Id,
WatchDate=r.WatchDate,
额定值=r.额定值,
UserId=r.User.Id,
UserEmail=r.User.Email,
})
.OrderByDescending(r=>r.Rating)
.ToListAsync();
返回视图(数据);
}
视图最好使用ViewModel
。因此,首先,创建一个ViewModel
类,如下所示:
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; }
}
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);
}
然后将查询投影到ViewModel
类型,如下所示:
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; }
}
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);
}
公共异步任务索引()
{
var data=wait_context.Reviews
.选择(r=>new ReviewViewModel{
Id=r.Id,
WatchDate=r.WatchDate,
额定值=r.额定值,
UserId=r.User.Id,
UserEmail=r.User.Email,
})
.OrderByDescending(r=>r.Rating)
.ToListAsync();
返回视图(数据);
}
您可以这样做。Select(p=>new{p.User.Email}).AsEnumerable()如果使用Select而不使用Include,则用户将为空。您可以这样做。Select(p=>new{p.User.Email})。AsEnumerable()如果使用Select而不使用Include,则用户将为Null您不需要编写r.User!=无效的r、 User.Email:null,
。EF Core将在生成SQL之前执行必要的操作。谢谢。答案已更新。对于我来说,这是一个很好的解决方案,可以防止空值错误。我太悲观了:)你不需要写r.User!=无效的r、 User.Email:null,
。EF Core将在生成SQL之前执行必要的操作。谢谢。答案已更新。对于我来说,这是一个很好的解决方案,可以防止空值错误。我太悲观了:))