>,c#,expression-trees"/>

首页 > 解决方案 > 扩展表达式>

问题描述

自从我深入研究表达式树以来已经有很长时间了,我正在努力解决以下问题。

基本上我想采取以下措施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?

    }

}

标签: c#expression-trees

解决方案


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

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您的适配器的实例在哪里。


推荐阅读