【问题标题】:The LINQ expression node type 'Invoke' is not supported in LINQ to Entities with skip带有跳过的 LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”
【发布时间】:2013-09-23 11:57:50
【问题描述】:

我有错误 LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。

var result = context.Users.Include("Roles")
                          .OrderBy(x => x.UserID)
                          .Where(x => !userIsAdmin(x))
                          .Skip(skip)
                          .Take(take)
                          .ToList();

private readonly Func<User, bool> userIsAdmin = u => u.Roles.Any(y => y.Name.Equals(AdminRoleName));

我哪里写错了?

【问题讨论】:

  • @Amit 在这里:.Where(x =&gt; !userIsAdmin(x))Where 从它的 lambda 参数构建一个表达式;在这个表达式中,userIsAdmin 是一个Func,因此,它被翻译成Expression.Invoke 而EntityFramework 不支持Expression.Invoke,因为它不知道如何将其翻译成SQL。

标签: c# linq


【解决方案1】:

LINQ to SQL 和 LINQ to Entities 都适用于 Expression,而不适用于 Func(就像 LINQ to Objects 一样),因此您必须将您的 userIsAdmin 声明为 Expression&lt;Func&lt;User, bool&gt;&gt;

private readonly Expression<Func<User, bool>> userIsAdmin = u => u.Roles.Any(y => y.Name.Equals(AdminRoleName));

您还应该考虑将表达式更改为:

private readonly Expression<Func<User, bool>> userIsAdmin = u => u.Roles.Select(y => y.Name).Contains(AdminRoleName));

应该在生成的 SQL 查询中翻译成IN 语句。

【讨论】:

  • 我有新错误-当前上下文中不存在名称'userIsAdmin'
  • 那根本行不通。 (x => !userIsAdmin(x)) 会出错,因为您不能调用这样的表达式,因为它不是委托。
【解决方案2】:

MarcinJuraszek 走在正确的轨道上。您可以将谓词更改为:

private readonly Expression<Func<User, bool>> userIsNotAdmin = u => !u.Roles.Any(y => y.Name.Equals(AdminRoleName));

请注意,这是您所拥有的倒置。

然后你应该可以这样称呼它:

var result = context.Users.Include("Roles")
                      .OrderBy(x => x.UserID)
                      .Where(userIsNotAdmin)
                      .Skip(skip)
                      .Take(take)
                      .ToList();

【讨论】:

    猜你喜欢
    • 2011-08-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多