扩展表达式<func<t, bool>>
Extending an expression<func<t, bool>>
自从我深入研究表达式树以来已经有很长一段时间了,我正在努力解决以下问题。
基本上我想采取以下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?
}
}
你必须构建新的表达式,因为表达式是不可变的。在这种情况下,您可以为新表达式重用现有表达式的主体和参数:
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<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?
}
}
你必须构建新的表达式,因为表达式是不可变的。在这种情况下,您可以为新表达式重用现有表达式的主体和参数:
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
是您的适配器实例。