C# &引用;LINQ表达式节点类型';调用&x27;在LINQ to Entities中不受支持难倒了!

C# &引用;LINQ表达式节点类型';调用&x27;在LINQ to Entities中不受支持难倒了!,c#,asp.net,linq,entity-framework,linq-to-entities,C#,Asp.net,Linq,Entity Framework,Linq To Entities,在稍后的EF中,我试图传入一个匿名函数,作为Linq查询的一部分。该函数将传入一个INT并返回一个BOOL(u.RelationTypeId是一个INT)。以下是我的函数的简化版本: public IEnumerable<UserBandRelation> GetBandRelationsByUser(Func<int, bool> relation) { using (var ctx = new OpenGroovesEntities()) {

在稍后的EF中,我试图传入一个匿名函数,作为Linq查询的一部分。该函数将传入一个INT并返回一个BOOL(u.RelationTypeId是一个INT)。以下是我的函数的简化版本:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(Func<int, bool> relation)
{
    using (var ctx = new OpenGroovesEntities())
    {
        Expression<Func<UsersBand, bool>> predicate = (u) => relation(u.RelationTypeId);

        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}
public IEnumerable GetBandRelationsByser(函数关系)
{
使用(var ctx=new OpenGroovesEntities())
{
表达式谓词=(u)=>关系(u.RelationTypeId);
var relations=ctx.UsersBands.Where(谓词);
//映射,其他东西,返回到业务层
返回关系。ToList();
}
}

然而,我得到了上面提到的错误。通过从函数中构建一个谓词,我似乎正在纠正所有问题。有什么想法吗?谢谢。

您试图在中传递任意.NET函数。。。实体框架如何希望将其转换为SQL?您可以将其更改为采用
表达式
,并从中构建
Where
子句,尽管这并不特别容易,因为您需要使用不同的参数表达式重写表达式(即,用调用
u.RelationTypeId
的表达式替换原始表达式树中的任何参数表达式)

老实说,为了在lambda表达式中指定
u.RelationTypeId
,您可以使用该表达式创建表达式树以传递到方法中,您最好使用:

public IEnumerable<UserBandRelation> GetBandRelationsByUser(
    Expression<Func<UsersBand, bool>> predicate)
{
    using (var ctx = new OpenGroovesEntities())
    {
        var relations = ctx.UsersBands.Where(predicate);

        // mapping, other stuff, back to business layer
        return relations.ToList();
    }
}
public IEnumerable GetBandRelationsByser(
表达式(谓词)
{
使用(var ctx=new OpenGroovesEntities())
{
var relations=ctx.UsersBands.Where(谓词);
//映射,其他东西,返回到业务层
返回关系。ToList();
}
}

我遇到了这个错误,我正在使用Joe Albahari提供的实体框架来构建动态
where
子句。如果您恰好处于相同的条件下,您应该调用
AsExpandable
方法:

如果使用实体框架进行查询,请将最后一行更改为:

返回objectContext.Products.AsExpandable().Where(谓词);

此方法是LINQKIT DLL的一部分,您可以通过NuGet包获取或访问它


现在一切都很好。

我知道这个答案已经很晚了,但是我遇到了同样的问题,它把我带到了这里,所以我想我应该分享我的解决方案


我读了莱尼尔的答案,它给了我一个想法。默认类型具有方法“AsEnumerable()”,其行为方式与此相同,从而减轻了问题。

您可以在
Where
请求之前调用
谓词上的
Expand()
方法。

谢谢。这是我的想法,但我的问题是UserBandRelation是一个模型,而UsersBand是我的实体模型。我使用automapper来映射这些。如果我尝试像映射表达式这样疯狂的操作,Automapper就会出现问题。有没有什么办法可以让我的实体保持分离?谢谢。@Ryan在这里的某个地方,这是我写的一个示例,它将发生在flatten
Expression.Invoke
中,以允许EF使用子表达式(L2S支持的现成功能)。当然,它仍然不能与代表一起工作-仅仅说重写器在某处…@Ryan,事实上-只需启用“内联”@Ryan@Marc还有,它包含了操作表达式所需的许多功能。我支持Chris关于LinqKit=>的建议,它使得将表达式谓词链接在一起变得非常容易。
AsEnumerable()
将导致
Where()
函数由Linq调用对象,而不是Linq调用实体。您知道
AsExpandable()是否
是否会对性能造成影响?我使用的是一个通用存储库,只是偶尔使用谓词生成器,是否值得为谓词构建创建一个单独的存储库方法?@Cody。。。我不知道。你最好直接问乔·阿尔巴里这是他的推特:@DoctorOreo您了解性能影响了吗?我的处境和你一样you@Marc你知道吗,我想从2014年4月起就开始使用它了,但我没有注意到任何问题。在生产应用程序中进行了一年半,没有人抱怨过。(这是一个大约有50个用户处理10000到5000000条记录的系统)看起来与最新版本类似,您不需要使用
AsExpandable()
将谓词传递到
Where()
。可能是因为新的
PredicateBuilder.new()
起点?这也很有效!我不知道AsExpandable做什么,所以我更喜欢在我真正想要过滤查询时调用Expand。