dotnet/efcore · error · ArgumentException

The provided DbFunction expression '{expression}' is invalid

Error message

The provided DbFunction expression '{expression}' is invalid. The expression must be a lambda expression containing a single method call to the target static method. Default values can be provided as arguments if required, e.g. '() => SomeClass.SomeMethod(null, 0)'.

What it means

ModelBuilder.HasDbFunction<TResult>(Expression<Func<TResult>>) requires the lambda body to be a single MethodCallExpression whose Method is the target static method (RelationalModelBuilderExtensions.cs:298, RelationalStrings.DbFunctionExpressionIsNotMethodCall). EF extracts the MethodInfo from expression.Body as MethodCallExpression; any other shape yields null and throws.

Source

Thrown at src/EFCore.Relational/Extensions/RelationalModelBuilderExtensions.cs:298

    /// <summary>
    ///     Configures a database function when targeting a relational database.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-database-functions">Database functions</see> for more information and examples.
    /// </remarks>
    /// <param name="modelBuilder">The model builder.</param>
    /// <param name="expression">The method this dbFunction uses.</param>
    /// <returns>A builder to further configure the function.</returns>
    public static DbFunctionBuilder HasDbFunction<TResult>(
        this ModelBuilder modelBuilder,
        Expression<Func<TResult>> expression)
    {
        Check.NotNull(expression);

        var methodInfo = (expression.Body as MethodCallExpression)?.Method;

        return methodInfo == null
            ? throw new ArgumentException(RelationalStrings.DbFunctionExpressionIsNotMethodCall(expression))
            : modelBuilder.HasDbFunction(methodInfo);
    }

    /// <summary>
    ///     Configures a database function when targeting a relational database.
    /// </summary>
    /// <remarks>
    ///     See <see href="https://aka.ms/efcore-docs-database-functions">Database functions</see> for more information and examples.
    /// </remarks>
    /// <param name="modelBuilder">The model builder.</param>
    /// <param name="methodInfo">The methodInfo this dbFunction uses.</param>
    /// <param name="builderAction">An action that performs configuration of the sequence.</param>
    /// <returns>A builder to further configure the function.</returns>
    public static ModelBuilder HasDbFunction(
        this ModelBuilder modelBuilder,
        MethodInfo methodInfo,
        Action<DbFunctionBuilder> builderAction)
    {

View on GitHub (pinned to dbf9771522)

Solutions

  1. Make the lambda body exactly one method call to the target static method, supplying default-typed arguments: () => MyType.MyMethod(null, 0).
  2. Prefer the MethodInfo overload: HasDbFunction(typeof(MyType).GetMethod(nameof(MyType.MyMethod))!).
  3. Ensure the target method is static and on the type registered; remove wrapping/composition from the expression.

Example fix

// before
modelBuilder.HasDbFunction(() => MyDb.Foo());           // ok if Foo() is the body
modelBuilder.HasDbFunction(() => 1 + MyDb.Foo());        // throws: body is Add, not MethodCall
modelBuilder.HasDbFunction(() => MyDb.Value);            // throws: body is MemberAccess

// after
modelBuilder.HasDbFunction(() => MyDb.Foo(null, 0));
// or
modelBuilder.HasDbFunction(typeof(MyDb).GetMethod(nameof(MyDb.Foo))!);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the lambda body is a single method call before registering.
Expression<Func<object>> expr = () => MyType.MyMethod(null, 0);
if (expr.Body is not MethodCallExpression mce)
    throw new ArgumentException("DbFunction expression must be a single method call.");
modelBuilder.HasDbFunction(mce.Method);

Type guard

static bool IsMethodCallLambda<T>(Expression<Func<T>> e) => e.Body is MethodCallExpression;

Prevention

When it happens

Trigger: Passing a lambda that is a property access, a field, a constructor call, a multi-statement block, a delegate invocation, or a method group rather than a direct call: e.g. () => MyHelpers.Total or () => 1 + Foo() instead of () => Foo(null, 0).

Common situations: Registering a DbFunction whose body wraps the call in arithmetic, calls an instance method, or references a property; converting a Func<T> delegate into an expression incorrectly; refactoring the static method signature.

Related errors


AI-assisted analysis of dotnet/efcore@dbf9771522 (2026-08-06). Data as JSON: /api/errors/e7a8890d34221f63. Report an issue: GitHub.