在 C# 表达式中使用枚举参数

Use enum parameter with c# expression

我想要一个将实体项转换为 DTO 对象的表达式,并使用附加参数 select 应将哪些数据复制到 DTO 中。在我添加参数之前,这非常有效:

    private static readonly Expression<Func<User, UserDataGroupType, UserData>> s_entityToDataExpression = (User entity, UserDataGroupType dataGroups) => new UserData
    {
        Id = entity.Id,
        State = entity.State,

        Role = entity.Role.ToData(),

        BaseData = dataGroups.HasFlag(UserDataGroupType.Base) ? entity.ToDataBase() : null,
        BirthData = dataGroups.HasFlag(UserDataGroupType.Birth) ? entity.ToDataBirth() : null,
        AddressData = dataGroups.HasFlag(UserDataGroupType.Address) ? entity.ToDataAddress() : null,
        ExtendedData = dataGroups.HasFlag(UserDataGroupType.Extended) ? entity.ToDataExtended() : null,
    };

private static readonly Func<User, UserDataGroupType, UserData> s_entityToDataDelegate = s_entityToDataExpression.Compile();

public static UserData ToData(this User entity, UserDataGroupType dataGroups) => s_entityToDataDelegate(entity, dataGroups);

public static IQueryable<UserData> ToData(this IQueryable<User> queryable, UserDataGroupType dataGroups) => queryable.Select(s_entityToDataExpression);

它抱怨最后一行的参数:

cannot convert from 'System.Linq.Expressions.Expression<System.Func<Entities.User, Enums.UserDataGroupType, UserData>>' to 'System.Linq.Expressions.Expression<System.Func<Entities.User, int, UserData>>'

int 是从哪里来的? UserDataGroupType 是字节类型标志枚举。

更新

在@guru-stron 建议的修改之后,工作代码如下所示:

private static Expression<Func<User, UserData>> GetToDataExpression(UserDataGroupType dataGroups) => (entity) => new UserData {...}
public static IQueryable<UserData> ToData(this IQueryable<User> queryable, UserDataGroupType dataGroups) => queryable.Select(GetToDataExpression(dataGroups));

Queryable.Select 有 2 个重载 Func 有一个和两个参数 -

  • Select<TSource,TResult>(IQueryable<TSource>, Expression<Func<TSource,Int32,TResult>>)
  • Select<TSource,TResult>(IQueryable<TSource>, Expression<Func<TSource,TResult>>)

第一个代表像 .Select((item, index) => ...) 这样的表达式,你的 s_entityToDataExpression 代表一个 Func 需要 2 个参数所以编译器试图将它转换为 Expression<System.Func<Entities.User, int, UserData>>,这不是可能。

您似乎需要将代码更改为:

private static Expression<Func<User, UserData>> GetExpression(UserDataGroupType dataGroups) => (User entity, UserDataGroupType ) => new UserData
{
    Id = entity.Id,
    State = entity.State,

    Role = entity.Role.ToData(),

    BaseData = dataGroups.HasFlag(UserDataGroupType.Base) ? entity.ToDataBase() : null,
    BirthData = dataGroups.HasFlag(UserDataGroupType.Birth) ? entity.ToDataBirth() : null,
    AddressData = dataGroups.HasFlag(UserDataGroupType.Address) ? entity.ToDataAddress() : null,
    ExtendedData = dataGroups.HasFlag(UserDataGroupType.Extended) ? entity.ToDataExtended() : null,
};

public static IQueryable<UserData> ToData(this IQueryable<User> queryable, UserDataGroupType dataGroups) 
     => queryable.Select(GetExpression(dataGroups));