【问题标题】:Inability to use "MaxBy" on "Where" clauses with EFCore + MySQL无法在 EF Core + MySQL 的“Where”子句中使用“BixBy”
【发布时间】:2022-07-13 04:13:36
【问题描述】:

我的数据库结构如下:

public class Ticket
{
    public int Id { get; set; }
    public List<History> Histories { get; set; }
}

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class History
{
    public int Id { get; set; }
    public Employee Employee { get; set; }
    public DateTime Timestamp { get; set; }
}

用户提供要过滤的属性名称和查询字符串。我想到的是我需要允许用户通过Tickets 中的计算属性查询Tickets,例如

public Employee LatestEmployee
{
    get => History.MaxBy(x=>x.Timestamp).Employee;
}

有人建议我严格保留实体模型以反映数据库结构并使用单独的类来表示实体的可查询属性:

public class TicketSummary
{
    public int TicketId {get;set;}
    public Employee LatestEmployee {get;set;}
}

public IQueryable<TicketSummary> BuildSummaryQuery()
{
    return _context.Tickets.Select(t => new TicketSummary
        {
            TicketId = t.Id,
            LatestEmployee = t.History.MaxBy(x=>x.Timestamp).Employee
        });
}

然后拨打BuildSummaryQuery().Where(x=&gt;x.LatestEmployee.Name == "Batman")。但是,我发现MaxBy() 无法转换为 MySQL 数据库上的有效查询。我不断收到The LINQ expression could not be translated。如何计算出类似的有效查询?

【问题讨论】:

    标签: c# mysql dynamic-linq ef-core-6.0


    【解决方案1】:

    根据 StriplingWarrior 的评论 (What is the correct way to use computed properties with Dynamic LINQ?),我没有使用 MaxBy(),而是成功地使用 OrderByDescending()FirstOrDefault() 创建了一个有效查询

    首先,实际的可查询实体不是实体上的计算属性,而是

    public class TicketSummary
    {
        public string TicketId { get; set; }
        public History? LatestHistory { get; set; }
    }
    

    那么,查询组成如下

    //Includes the tables needed for the filterable properties.
    var firstQuery = _context.Tickets.Include(t => t.Histories).ThenInclude(h => h.Employee);
    
    //Creates an IQueryable<TicketSummary> with the latest History entity
    var ticketSummariesQueryable = firstQuery.Select(x => new TicketSummary
    {
        TicketId = x.Id.ToString(),
        LatestHistory = x.Histories.OrderByDescending(x=>x.Timestamp).FirstOrDefault()
    });
    
    //Finally apply the filters given by the user
    var filteredQuery = ticketSummariesQueryable.Where(ts=>ts.LatestHistory.Employee.Name == "Black Canary");
    

    这样,最新的History 存储在LatestHistory 上,以便及时用于查询。

    【讨论】:

      猜你喜欢
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 2021-08-26
      • 2022-01-14
      相关资源
      最近更新 更多