Расширение выражения <func <t, bool >> - PullRequest
0 голосов
/ 28 апреля 2018

Прошло много времени с тех пор, как я копался в деревьях выражений и борюсь со следующей проблемой.

В основном я хочу взять следующее 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 Ответ

0 голосов
/ 28 апреля 2018

Вы должны построить новое выражение, потому что выражения неизменны. В этом случае вы можете повторно использовать тело и параметры существующего выражения для нового:

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 - это экземпляр вашего адаптера.

...