具有过滤、分页、排序和排序方向的 EF Core 调用

问题描述 投票:0回答:1

我需要编写一个 EF 查询,它将返回

Event
对象的列表,但还包括子对象 (
User
),并且还对父对象和子对象中的某些属性使用过滤、使用分页、使用排序和排序方向(升序/降序)- 全部基于提供的参数。

我编写了查询的早期版本,它确实部分有效并且返回了一些值。这里的问题是:

  • 我无法选择排序方向,因为这需要有条件地调用
    OrderBy()
    OrderByDescending()
  • 对于排序,我无法使用子对象内部的属性,因为这需要无条件地直接在查询中提供它(我需要编写
    OrderBy(prop => EF.Property<object>(prop.User, sortBy))
    )。

查询:

var query = _db.Event
    .AsNoTracking()
    .Include(e => e.User)
    .Where(e => e.User.UserName.Contains(filterText)
        || e.EventCode.Contains(filterText))
    .OrderBy(prop => EF.Property<object>(prop, sortBy))
    .Skip(page * itemsPerPage)
    .Take(itemsPerPage)
    .ProjectToType<EventModel>()
    .ToListAsync(cancellationToken)
    ;

return result;

然后我尝试将查询分割成更小的部分,以便我可以将其进一步分割并引入条件,但现在由于某种原因结果完全为空。

var query = _db.Event
    .AsNoTracking()
    .Include(e => e.User)
    .Where(e => e.User.UserName.Contains(filterText)
        || e.EventCode.Contains(filterText))
    .OrderBy(prop => EF.Property<object>(prop, sortBy))
    .Skip(page * itemsPerPage)
    .Take(itemsPerPage)
    ;

var result = await query
    .ProjectToType<EventModel>()
    .ToListAsync(cancellationToken);

return result;

Event
班:

public class Event 
{
    [Key]
    public int EventId { get; set; }
    [Required]
    [MaxLength(64)]
    public string EventCode { get; set; }
    public DateTime DateTime { get; set; }
    [Required]
    public int UserID { get; set; }
    public User User { get; set; }
}

如何编写包含我需要的所有条件的查询?

c# entity-framework-core .net-8.0
1个回答
0
投票

为什么不从这样的查询开始:

var query = _db.Event
.AsNoTracking()
.Include(e => e.User)
.Where(e => e.User.UserName.Contains(filterText)
    || e.EventCode.Contains(filterText));

然后添加条件排序:

if (ascending)
{
    query = query.OrderBy(prop => EF.Property<object>(prop, sortBy));
}
else
{
    query = query.OrderByDescending(prop => EF.Property<object>(prop, sortBy));
}

我对ProjectToType一无所知,如果它使用Expression>,那么它可以工作:

Expression<Func<Event, TEventModel>> ProjectToType<TEventModel>(IQueryable<Event> query)
{
    //use some mapper that works with Expression<Func<Event, TEventModel>> to map to the new type, maybe AutoMapper
}

然后致电:

var result = await query
.ProjectToType<EventModel>()
.ToListAsync(cancellationToken);
© www.soinside.com 2019 - 2024. All rights reserved.