我很难创建满足我要求的LINQ-to-Entities查询。
我有两个表:Booking和ProcessStatusLog
预订表:
ProcessStatusLog表:
以下是这些表的示例数据:
预订桌
|----------|----------------|
| PNNumber | Account Name |
|----------|----------------|
| 11111 | Boston Celtics |
|----------|----------------|
| 22222 | Miami Heat |
|----------|----------------|
ProcessStatusLog表
|------|-----------|---------------|--------------|-------------|
| ID | PNNumber | InsuranceCode | Status | UpdatedOn |
|------|-----------|---------------|--------------|-------------|
| 1 | 11111 | FIRE | NEW | 02/22/2020 |
|------|-----------|---------------|--------------|-------------|
| 2 | 11111 | FIRE | FOR REVIEW | 02/23/2020 |
|------|-----------|---------------|--------------|-------------|
| 3 | 22222 | FIRE | NEW | 02/24/2020 |
|------|-----------|---------------|--------------|-------------|
| 4 | 22222 | MORTGAGE | NEW | 02/25/2020 |
|------|-----------|---------------|--------------|-------------|
| 5 | 22222 | MORTGAGE | FOR REVIEW | 02/26/2020 |
|------|-----------|---------------|--------------|-------------|
| 6 | 22222 | FIRE | CANCELLED | 02/28/2020 |
|------|-----------|---------------|--------------|-------------|
现在,我想获取每个保险代码的单个PN的最新状态。
例如:我想获取PNNumber 11111的最新状态。我想获取的输出是“ FOR REVIEW”。
对于PNNumber 22222,所需的输出将是“ FOR REVIEW,CANCELLED”
如何为此编写EF查询?谢谢。
重新创建的数据库:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Booking>().HasKey(b => b.PNNumber);
modelBuilder.Entity<Booking>().HasData(
new Booking { PNNumber = "11111", AccountName = "Boston Celtics" },
new Booking { PNNumber = "22222", AccountName = "Miami Heat" });
modelBuilder.Entity<ProcessStatusLog>().HasData(
new ProcessStatusLog { ID = 1, PNNumber = "11111", InsuranceCode = "FIRE", Status = "NEW", UpdatedOn = DateTime.Parse("22/02/2020") },
new ProcessStatusLog { ID = 2, PNNumber = "11111", InsuranceCode = "FIRE", Status = "FOR REVIEW", UpdatedOn = DateTime.Parse("23/02/2020") },
new ProcessStatusLog { ID = 3, PNNumber = "22222", InsuranceCode = "FIRE", Status = "NEW", UpdatedOn = DateTime.Parse("24/02/2020") },
new ProcessStatusLog { ID = 4, PNNumber = "22222", InsuranceCode = "MORTGAGE", Status = "NEW", UpdatedOn = DateTime.Parse("25/02/2020") },
new ProcessStatusLog { ID = 5, PNNumber = "22222", InsuranceCode = "MORTGAGE", Status = "FOR REVIEW", UpdatedOn = DateTime.Parse("26/02/2020") },
new ProcessStatusLog { ID = 6, PNNumber = "22222", InsuranceCode = "FIRE", Status = "CANCELLED", UpdatedOn = DateTime.Parse("28/02/2020") });
base.OnModelCreating(modelBuilder);
}
查询:
public IActionResult Index()
{
this.dbContext.Database.EnsureCreated();
string givenPNNumber = "22222";
var filteredLogs = dbContext.ProcessStatusLog
.Where(log => log.PNNumber == givenPNNumber);
// Get date of the latest log for each incurance code for eaxh PNNumber.
var groupedLogs = filteredLogs
.GroupBy(psl => psl.InsuranceCode)
.Select(group => new
{
Code = group.Key,
LastUpdate = group.Max(g => g.UpdatedOn)
});
var result =
from logs in filteredLogs
join latestLogs in groupedLogs
on logs.InsuranceCode equals latestLogs.Code into joined
from j in joined.DefaultIfEmpty()
where logs.UpdatedOn == j.LastUpdate
select logs.Status;
string finalResult = string.Join(',', result.ToList());
return View();
}
因为我只使用了内存中的Db,所以我不知道EF将如何生成查询,但是查询的计划是:
PNNumber
的日志列表,InsuranceCode
的PNNumber
列表以及该PNNumber
和InsuranceCode
的任何日志的最新日期InsuranceCode
,UpdatedOn
,Max(UpdatedOn)
的列表UpdatedOn == Max(UpdatedOn)
的行(给定InsuranceCode
的所有PNNumber
的最新实体)Status
es我不知道它是否将直接转换为SQL,或者您需要首先获取整个列表,但是您应该可以使用[GroupBy][1]
方法来实现。
假设您的Booking
模型有一个名为ProcessStatusLog
的ProcessStatusLogs
对象的列表,它应该看起来像这样:
var result = bookings.GroupBy(
x => x.Id,
(_, g) => g.SelectMany(x => x.ProcessStatusLogs)
.OrderByDescending(x => x.UpdatedOn)
.FirstOrDefault()
);