扩展一个表达式<func<t, bool>>

3
我已经很久没有深入研究表达式树了,我正在为以下问题而苦苦挣扎。
基本上,我想要使用以下Expression<Func<T, TIdType>>(a) => EF.Property<TIdType>(a, "TenantId") 并将其扩展为以下Expression<Func<T, bool>(a) => EF.Property<TIdType>(a, "TenantId").Equals(TenantId) 所以基本上我想要取得原始表达式并添加.Equals(TenantId)
关于这个问题的背景,这都是因为我试图解决EF Core 2.0中的一个问题,如下所述: https://github.com/aspnet/EntityFrameworkCore/issues/11456 以下详细说明了我正在尝试的内容:
public class FooEntity
{
    public Guid TenantId { get; set; }
}

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {

        var adaptor = new TenantFilterExpressionAdaptor<FooEntity, Guid>();
        var tenantIdFilter = adaptor.Adapt((a) => EF.Property<Guid>(a, "TenantId"));

    }
}

public class TenantFilterExpressionAdaptor<T, TIdType>
{

    public TIdType TenantId { get; set; }

    public Expression<Func<T, bool>> Adapt(Expression<Func<T, TIdType>> idExpression)
    {

        // Tack on .Equals(TenantId) to the expression!?

        // assume I have to add nodes to the body?
        // idExpression.Body?

    }

}
1个回答

5

你需要构建新的表达式,因为表达式是不可变的。在这种情况下,您可以重用现有表达式的主体和参数来创建新的表达式:

public class TenantFilterExpressionAdaptor<T, TIdType> {

    public TIdType TenantId { get; set; }

    public Expression<Func<T, bool>> Adapt(Expression<Func<T, TIdType>> idExpression) {
        return Expression.Lambda<Func<T, bool>>(
            Expression.Equal(idExpression.Body, Expression.Constant(TenantId)),
            idExpression.Parameters);
    }
}

你在评论中提到常量对你来说有问题。在这种情况下,你可以引用属性本身而不是它的值:

return Expression.Lambda<Func<T, bool>>(
    Expression.Equal(idExpression.Body, Expression.Property(Expression.Constant(this), nameof(TenantId))),
    idExpression.Parameters);

这将是类似于表达式的内容:
x => x.TenantId == this.TenantId

这里的this是您适配器的实例。


谢谢。在那个解决方案中,Expression.Constant(TenantId) 对我来说有问题,因为 TenantId 的值需要在运行时提供(因为它会改变)。我需要将其转换为参数吗?有没有可能扩展您的答案以解决这个问题,以获得额外的赞? :-) - Darrell
@Darrell,这是什么问题?你要在某个地方缓存该表达式并重复使用吗?通常这不是一个好主意,你应该根据需要构建表达式。 - Evk
我知道,在这种情况下,它是一个EF表达式,EF会缓存并重复使用它。我完全无法控制它... :-( - Darrell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接