如何将 Expression<Func<T, object>> 转换为 Expression<Func<T, bool>>?

How do I convert Expression<Func<T, object>> to Expression<Func<T, bool>>?

我可以找到很多有关如何更改表达式主体的信息,但找不到有关如何更改 ReturnType 的任何信息。

这是我编写的包含对下面给出的 Convert 例程的调用的代码。

    private T[] CheckCreatedOnDate<T>(Expression<Func<T, object>> fieldExpression, T[] input, Data.Context context) where T : Entity
    {
        var fieldDelegate = fieldExpression.Compile();

        Expression<Func<T, bool>> predicateExpression = Convert(fieldExpression);  
        Func<T, bool> predicateDelegate = predicateExpression.Compile();
        Predicate<T> predicate = predicateDelegate.Invoke;

        DbSet<T> dbSet = context.Set<T>();
        var data = dbSet.ToList();

        foreach (T inputRecord in input)
        {
            var fieldObject = fieldDelegate.Invoke(inputRecord);

            var dataRecord = data.SingleOrDefault(x => Equals(predicate, fieldObject));

            if (dataRecord != null)
            {
                inputRecord.CreatedOn = dataRecord.CreatedOn;
            }
        }

        return input;
    }

此方法的行为方式应与 EF 中的 AddOrUpdate 方法非常相似,但如果记录已在 Db 中,则此方法仅替换 createdOn 日期。

但是我的代码仍然不起作用。创建的谓词似乎不正确,因为它从未在 Db 中找到相关记录。

非常感谢大家的帮助。

迈克干杯

假设 fieldExpression 类似于 (T e) => e.Field 我得出的结论是您希望在 Field 列中找到具有相同值的数据库记录。

试试这个:

foreach (T inputRecord in input)
{
    object fieldObject = fieldDelegate.Invoke(inputRecord);

    ParameterExpression p = fieldExpression.Parameters.First();
    // Equivalent to x => x.Field == fieldObject
    Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(
        // input.Field == fieldObject
        Expression.Equal(
            // input.Field
            fieldExpression.Body,
            // constant from fieldObject
            Expression.Constant(fieldObject)
        ),
        new []{ p }
    );

    T dataRecord = dbSet.SingleOrDefault(predicate);

    if (dataRecord != null)
    {
        inputRecord.CreatedOn = dataRecord.CreatedOn;
    }
}

我在每个循环 运行 中创建了全新的谓词,方法是采用 fieldExpression 主体并将其传递给 SingleOrDefault 调用。