繁体   English   中英

EF Core 查询问题

[英]Issue with an EF Core query

我正在尝试为与EF Core中的另一个实体具有一对多关系的实体创建查询。

这是两个实体:

public class Computer {
  public int ComputerId { get; set; }
  public string Hostname { get; set; }
  public string IpAddress { get; set; }

  public ICollection<Event> Events { get; set; }
}

public class Event {
  public int EventId { get; set; }
  public string Description { get; set; }
  public DateTime EventTime { get; set; }

  public Computer Computer { get; set; }
}

我试图找出如何使用最新Event的 EventId 查询所有Computer记录的EventId

我了解如何对每个进行简单查询,我 go 如何编写一个查询来返回我需要的数据?

较新版本的 EF Core (5+) 了解如何将其转换为 ROW_NUMBER OVER,这是获得所需内容的有效方法:

context.Computers
  .Select(c => new {
    Computer = c, //or just take some properties from it
    RecentEvent = c.Events.OrderByDescending(e => e.EventTime).FirstOrDefault()
  });

它被写入如下内容:

SELECT *
FROM
  Computers c
  INNER JOIN (
    SELECT *, ROW_NUMBER() OVER(PARTITION BY ComputerId ORDER BY EventTime DESC) rn
    FROM Events
  ) e ON c.ComputerId = e.ComputerId AND rn = 1

神奇的是“and rn=1”


这会获取每个 object 的全部,但如果需要,您可以只获取 ID select(我假设您想要来自事件的更多数据)。

在我的脑海中,您可能想要类似的东西。 我的子句可能排序有误,但我总是需要处理 EF Core 查询。

using var ctx = new MyDatabaseContext();

var newestEventsForEachComputer =
    ctx.Events
       .AsNoTracking()
       .Include(e => e.Computer)
       .OrderByDescending(e => e.EventTime)
       .GroupBy(e => e.Computer.Id)
       .Select(g => g.First())
       .ToList();

注意:根据您对表链接的描述,我假设.Include子句在那里是有效的。

你可以试试这个,结果将是一个计算机列表,他们将有一个列表,其中只有一个具有最新 ID 的事件

dbContext.Computer.Include(x => x.Event.OrderByDescending(x => x.Id).Take(1)).Select(x => x).ToList();

首先,您需要在模型之间建立适当的关系。 如果您使用代码优先方法 go。 按照下面的代码片段

 public class Computer
{
    [Key]
    public int ComputerId { get; set; }
    public string Hostname { get; set; }
    public string IpAddress { get; set; }

    [InverseProperty("Computer")]
    public ICollection<Event> Events { get; set; }
}


public class Event
{
    [Key]
    public int EventId { get; set; }
    public string Description { get; set; }
    public DateTime EventTime { get; set; }
    public Computer Computer { get; set; }
}

现在你已经在计算机和事件 model 之间建立了良好的关系。

现在,计算机实体拥有自己的事件集合,并且这些事件具有相同的计算机实体。

但是您不能仅通过查询单个 eventId 来获取计算机的集合。 因为你们的关系不是那样的。 你可以这样查询

 [HttpGet]
    public async Task<IActionResult> GetByIdAsync(int id)
    {
        var result = await _context.Computers.Include(a => a.Events).FirstOrDefaultAsync(a => a.ComputerId == id);
        return new JsonResult(result);
    }

这将返回具有相关事件的特定计算机。

暂无
暂无

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

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