【问题标题】:How to specify a default Sort with Hotchocolate and EF Core?如何使用 Hotchocolate 和 EF Core 指定默认排序?
【发布时间】:2022-08-02 20:54:56
【问题描述】:

有没有办法添加一个默认排序字段,这样我就可以UsePagingUserSorting,但是如果没有指定顺序,我会添加一个字段,例如 Id。但如果用户确实指定了订单,则不要添加默认值。

例如,我可以将默认排序添加到查询方法,但没有其他排序工作

[UseContext]
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<Property> GetProperties([ScopedService] PropContext dbContext)
{
    return dbContext.Properties
                    .OrderBy(p => p.Id); // Default sort by Prop Id
} 

如果没有排序,则 Entity Framework 会显示警告:

该查询使用不带 \'OrderBy\' 运算符的行限制运算符 (\'Skip\'/\'Take\')。
这可能会导致不可预知的结果

而且我看到了一些意想不到的结果

    标签: entity-framework-core hotchocolate


    【解决方案1】:

    归功于 S Blomstrand

    使用这些扩展方法

    public static bool HasOrderByArgument(this IResolverContext context,
                                           string argumentName = "order")
    {
        try
        {
            var orderByArgument = context.ArgumentLiteral<IValueNode>(argumentName);
            if (orderByArgument != NullValueNode.Default && orderByArgument != null)
            {
                return true;
            }
        }
        catch
        {
            return false;
        }
    
        return false;
    }
    
    public static IQueryable<T> OrderByArgumentOrDefault<T>(this IQueryable<T> query, IResolverContext context, 
                                                            Func<IQueryable<T>> func, string argumentName = "order")
    {
        if (context.HasOrderByArgument(argumentName))
        {
            return query;
        }
    
        return func.Invoke();
    }
    

    然后可以如下调用:

    [UseContext]
    [UsePaging]
    [UseProjection]
    [UseFiltering]
    [UseSorting]
    public IQueryable<Property> GetProperties([ScopedService] PropContext dbContext)
    {
        return dbContext.Properties
                        .OrderByArgumentOrDefault(context, () => properties.OrderBy(p => p.Id));
    } 
    

    【讨论】:

    • 嘿,这对我有用,但确实花了我几分钟的时间来弄清楚扩展方法需要进入哪些文件。您是否有机会提供更多关于此的上下文以帮助人们在未来解决问题?
    • 扩展方法可以进入任何静态类,然后使用 <namespace> 将命名空间导入查询类。它的基本扩展方法使用,docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
    【解决方案2】:

    Kerr/Blomstrand 对这个问题的回答并不像我写的那样对我有用

    以下更改确实有效:

    • 在查询方法中需要一个IResolverContext 参数(运行时会填充它,不需要属性)
    • Func 更改为Expression
       public static IQueryable<T> OrderByArgumentOrDefault<T>(
            this IQueryable<T> query,
            IResolverContext context,
            Expression<Func<IQueryable<T>>> expression,
            string argumentName = "order")
        {
            return context.HasOrderByArgument(argumentName) ? query : expression.Compile().Invoke();
        }
    
    
    public IQueryable<Property> GetProperties(
      [ScopedService] PropContext dbContext,
      IResolverContext context)
    {
        return dbContext.Properties
                        .OrderByArgumentOrDefault(context, () => dbContext.Properties.OrderBy(p => p.Id));
    } 
    

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 2015-06-22
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2023-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多