组合表达式树 [英] Combining expression trees

查看:194
本文介绍了组合表达式树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有如下表达式:

public Expression<Func<T, bool>> UserAccessCheckExpression<T>(int userId) where T : class
{
    return x => (IsAdmin || userId == CurrentUserId || userId == 0);
}

然后我想将这个过滤器应用到这样的几个集合(IQueryable) :

Then I want to apply this filter to several collections (IQueryable) like this one:

return tasks
  .Where(t => t.TaskUsers
     .Any(x => UserAccessCheckExpression<TaskUser>(x.User) && x.SomeBool == true));

在这样做时我收到以下错误:

I'm getting the following error while doing so:


错误40不能将类型 System.Linq.Expressions.Expression< System.Func< TaskUser,bool>> 隐式转换为 bool

我无法使用界面继承的解决方法(如TaskUser继承接口与int UserId属性(其中T:IHasUserId)),因为我想组合逻辑。

I can't use workaround with interface inheritance (like TaskUser inherits interface with int UserId property (where T : IHasUserId)) since I want to combine logic.

推荐答案

问题是, code> UserAccessCheckExpression()方法返回一个表达式 Any()方法是期待一个布尔值

The problem is that your UserAccessCheckExpression() method is returning an Expression while the Any() method is expecting a boolean.

现在,您可以将代码编译为 Expression 并调用方法(使用 UserAccessCheckExpression< TaskUser>(x.User).Compile()。Invoke(x.User) ),但是在运行时显然会失败,因为Linq-to-En tities将无法将您的 Any()转换为商店查询,因为它不再包含表达式

Now, you can get your code to compile by compiling the Expression and invoking the method (using UserAccessCheckExpression<TaskUser>(x.User).Compile().Invoke(x.User)) but that would obviously fail on runtime because Linq-to-Entities wouldn't be able to translate your Any() to a store query as it no longer contains an Expression.

LinqKit 旨在解决这个问题,使用自己的调用扩展方法,让代码编译,确保你的表达式将被替换使用另一个扩展名为 AsExpandable()的扩展方法返回到其原始格式。

LinqKit is aiming to solve this problem using its own Invoke extension method that while letting your code compile, will make sure your Expression will get replaced back to its original form using another extension method named AsExpandable() that is extending the entity set.

尝试这个:

using LinqKit.Extensions;

return tasks
      .AsExpandable()
      .Where(t => t.TaskUsers.Any(
                       x => UserAccessCheckExpression<TaskUser>(x.User).Invoke(x)
                            && x.SomeBool == true));

更多关于LinqKit

这篇关于组合表达式树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆