嵌套表达式函数时,LINQ不支持“调用”节点

时间:2016-10-22 11:29:53

标签: c# entity-framework linq lambda

我正在尝试嵌套Expression Functions,我尝试了多项内容(InvokeCompile等)并阅读了有关此异常的主题,但没有看到任何附加内容的情况嵌套表达式函数。我不太了解它,这对我来说很新鲜,我想我一定很想念一些非常简单的东西 我的目的是能够嵌套表达式,以便GetAbilities可以在多个其他表达式中使用,而不必复制其代码。

我怎么能实现这样的目标?

public static Expression<Func<User, bool>> Test
    {
        get
        {
            Expression<Func<User, bool>> res = (u => GetAbilities.Compile()(u).Any());
            return res;
        }
    }

    public static Expression<Func<User, IEnumerable<Ability>>> GetAbilities
    {
        get
        {
            Expression<Func<User, IEnumerable<Ability>>> res = u => u.AllAbilities.Where(a => a.Type == Ability.TypeE.Initial);
            return res;
        }
    }

在上面的例子中,当检索Test的结果时,我得到了以下例外:

  

LINQ to Entities中不支持LINQ表达式节点类型“Invoke”。

更新

请参阅下面的工作接受解决方案:)
由于现在正在运行,有人会知道应该对这些未映射的属性做些什么吗?具体而言,GetAbilities方法引用User类中的另一个方法,但我不能直接在查询中使用它,因为这是一个未映射的方法。所以问题是我应该将Abilities属性保留在User类中以供内部使用而静态GetAbilities用于查询目的(但这在某种程度上是复制代码),或者可能是编译和调用GetAbilities类中的静态User

保持它看起来不是很干净和可维护(这里似乎很简单,但实际功能更复杂):

// Used for queries
public static Expression<Func<User, IEnumerable<Ability>>> GetAbilities
{
    get
    {
        Expression<Func<User, IEnumerable<Ability>>> res = u => u.AllAbilities.Where(a => a.Type == Ability.TypeE.Initial);
        return res;
    }
}

// Used for internal purpose
public IEnumerable<Ability> Abilities
{
    get
    {
        return AllAbilities.Where(a => a.Type == Ability.TypeE.Initial);
    }
}

1 个答案:

答案 0 :(得分:2)

您可以使用LinqKit执行以下操作:

public static Expression<Func<User, bool>> Test
{
    get
    {
        //Use one expression inside another via Invoke
        Expression<Func<User, bool>> res = (u => GetAbilities.Invoke(u).Any());

        return res.Expand(); //Expand to create a full expression

        //The result would be the same as if you have used
        //u => u.AllAbilities.Where(a => a.Type == Ability.TypeE.Initial).Any()

    }
}