You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AutoMapper映射OData has操作符至HasFlag引发EF Core翻译异常

问题:AutoMapper OData EF Core中Flags枚举的$filter has操作失败

从AutoMapper.Extensions.OData仓库指引至此,咨询以下问题,不确定是否与AutoMapper.AspNetCore.OData.EFCore、AutoMapper.Extensions.ExpressionMapping相关。已准备复现问题的示例仓库,项目搭建及运行步骤见仓库README。

问题概述

我有领域实体Foo和DTOFoo,二者均包含Flags枚举类型FooType,代码如下:

namespace Domain.Enumerations;
[Flags]
public enum FooType
{
    One =   0b0001,
    Two =   0b0010,
    Three = 0b0100,
    Four =  0b1000
}

namespace Domain.Components.Foos;

public class Foo
{
    public Guid Id { get; set; }
    public FooType Type { get; set; }
}

namespace ApiModel;

[Flags]
public enum FooType
{
    One =   0b0001,
    Two =   0b0010,
    Three = 0b0100,
    Four =  0b1000
}

public class Foo
{
    public Guid Id { get; set; }
    public FooType Type { get; set; }
}

领域实体Foo通过EF Core绑定数据库,DTOFoo用于构建OData EDM。使用AutoMapper的OData/EFCore/ExpressionMapping扩展实现实体与模型间的转换。

当使用$filter=type eq 'Four'查询API时一切正常,但使用$filter=type has 'Four'时,应用抛出异常:

System.InvalidOperationException: LINQ表达式'DbSet().Where(f => f.Type.HasFlag((Enum)Four))'无法被翻译。
补充信息:方法'System.Enum.HasFlag'的翻译失败。若该方法可映射到自定义函数,请查看相关文档了解更多信息。请将查询重写为可翻译的形式,或通过调用'AsEnumerable'、'AsAsyncEnumerable'、'ToList'或'ToListAsync'显式切换为客户端评估。查看相关文档了解更多信息。

at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_01.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetAsyncEnumerator(CancellationToken cancellationToken) at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable1 source, CancellationToken cancellationToken) at AutoMapper.AspNet.OData.QueryableExtensions.GetAsync[TModel,TData](IQueryable1 query, IMapper mapper, Expression1 filter, Expression1 queryFunc, ICollection1 includeProperties, AsyncSettings asyncSettings) at AutoMapper.AspNet.OData.QueryableExtensions.GetAsync[TModel,TData](IQueryable1 query, IMapper mapper, ODataQueryOptions`1 options, QuerySettings querySettings)
at Domain.Components.Foos.Queries.GetFoosODataQueryHandler.Handle(GetFoosODataQuery query, CancellationToken ct) in C:\Projects\AutoMapper.OData.EFCore.Issue\Domain\Components\Foos\Queries\GetFoosOData.cs:line 29

在旧项目中,直接将DbSet<Foo>作为IQueryable从控制器返回时,flags enum的has操作可正常工作,但版本化API中这种方式不可行,因为API契约与数据库架构并非一一对应。曾考虑用数据库视图作为转换层再暴露为OData EDM,但架构设计上不理想。

表达式映射调试

添加单元测试对比两个表达式的差异:

直接针对领域实体的表达式:

Expression<Func<Foo, bool>> filter = x => x.Type.HasFlag(FooType.Three);

通过AutoMapper映射后的表达式:

Expression<Func<ApiModel.Foo, bool>> modelFilter = x => x.Type.HasFlag(ApiModel.FooType.Three);
var filter = _mapper.MapExpression<Expression<Func<Foo, bool>>>(modelFilter);

目前未发现两个filter的差异,但前者可正常工作,后者抛出上述异常。

请问有人遇到过类似问题吗?希望继续用AutoMapper实现层间映射,不想将该职责转移到数据库。

感谢关注!


内容的提问来源于stack exchange,提问作者engenb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:51:02