同一上下文中的任意表达式错误:静态方法需要空实例

本文关键字:静态方法 实例 错误 表达式 上下文 任意 | 更新日期: 2023-09-27 18:32:49

我有这个错误:

System.ArgumentException:静态方法需要空实例,非静态方法需要非空实例。 参数名称:方法

但它在一个地方被提出,而在另一个地方,在同样的情况下,它没有。例如,在这种用法中,一切正常:

    public async Task<ValueServiceResult<PagedEnumerable<GenreDto>>> List(int page, int pageSize, int? parentCategory = null)
    {
        return await TryCatchAsync(async () =>
        {
            var whereQuery = parentCategory.HasValue
                ? GetExpression<Genre>(g => g.ParentCategoryId == parentCategory.Value)
                : null;
            var items = await Repository.GeneralQueryPaged(page, pageSize, whereQuery,
                c => c.Name);
            var mappedResult = Mapper.Map<IEnumerable<GenreDto>>(items);
            return new ValueServiceResult<PagedEnumerable<GenreDto>>(new PagedEnumerable<GenreDto>(mappedResult, items.Total, pageSize));
        });
    }

在另一种用法中,它引发了异常:

    public async Task<ValueServiceResult<PagedEnumerable<ArtistDto>>> List(int page, int pageSize, string filter)
    {
        return await TryCatchAsync(async () =>
        {
            if (!string.IsNullOrEmpty(filter))
                filter = filter.Trim().ToLower();
            var whereQuery = !string.IsNullOrEmpty(filter)
                ? GetExpression<Artist>(a => true) /*a.Name.ToLower().Contains(filter)*/
                : null;
            var items = await Repository.GeneralQueryPaged(page, pageSize, whereQuery, c => c.Name);
            var mappedResult = Mapper.Map<IEnumerable<ArtistDto>>(items);
            return new ValueServiceResult<PagedEnumerable<ArtistDto>>(new PagedEnumerable<ArtistDto>(mappedResult, items.Total, pageSize));
        });
    }

GetExpression调用中引发异常。这是父类中的静态方法。这是它的实现方式:

    public static Expression<Func<TEntity, bool>> GetExpression<TEntity> (Func<TEntity, bool> funct)
    {
        return Expression.Lambda<Func<TEntity, bool>>(Expression.Call(funct.Method));
    } 

我只是不明白,为什么有可能在一种用法中引发此错误,而在另一种用法中却没有。我在这里错过了什么?

同一上下文中的任意表达式错误:静态方法需要空实例

> 不要使用 Expression.Call ,它仅用于调用实际方法。

使用 Expression.Invoke 调用委托。

有很多

原因可以解释为什么Call在某些地方可能有效,但在其他地方不起作用 - 最有可能的是,有效的那种有关闭,而那些不工作的......不。不过,我仍然希望一切都会在运行时中断,因为您永远不会将正确的参数传递给Expression.Call - 您需要传递 lambda 参数(在闭包情况下,传递闭包实例)。

请注意,如果使用此帮助程序方法与实体框架之类的内容进行交互,则它很可能无论如何都不起作用 - 在 C# 中,方法不会自动用引号括起来,因此 EF 看到的只是方法调用 - 它不会在方法内部看到。如果您只使用它稍后调用(例如使用 Compile().Invoke()),不过,你没事。

代码示例:

public static Expression<Func<TEntity, bool>> Wrap<TEntity>(Func<TEntity, bool> func)
{
    var entity = Expression.Parameter(typeof(TEntity));
    return 
        Expression.Lambda<Func<TEntity, bool>>
        (
            Expression.Invoke(Expression.Constant(func), entity), 
            entity
        );
}