Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将LinqKit PredicateBuilder用于相关模型(EF Core)_C#_Linq_.net Core_Entity Framework Core_Linqkit - Fatal编程技术网

C# 将LinqKit PredicateBuilder用于相关模型(EF Core)

C# 将LinqKit PredicateBuilder用于相关模型(EF Core),c#,linq,.net-core,entity-framework-core,linqkit,C#,Linq,.net Core,Entity Framework Core,Linqkit,我想使用LinqKit的PredicateBuilder,并将谓词传递到相关模型的.Any方法中 所以我想构建一个谓词: var castCondition = PredicateBuilder.New<CastInfo>(true); if (movies != null && movies.Length > 0) { castCondition = castCondition.And(c => movies.Contains(c.MovieI

我想使用LinqKit的PredicateBuilder,并将谓词传递到相关模型的
.Any
方法中

所以我想构建一个谓词:

var castCondition = PredicateBuilder.New<CastInfo>(true);

if (movies != null && movies.Length > 0)
{
    castCondition = castCondition.And(c => movies.Contains(c.MovieId));
}
if (roleType > 0)
{
    castCondition = castCondition.And(c => c.RoleId == roleType);
}
IQueryable<Name> result = _context.Name.AsExpandable().Where(n => n.CastInfo.Any(castCondition));
return await result.OrderBy(n => n.Name1).Take(25).ToListAsync();
或者直接使用compile

IQueryable<Name> result = _context.Name.AsExpandable().Where(n => n.CastInfo.Any(castCondition.Compile()));
所以我想我只是错过了一些关于建设者的东西


关于版本的更新:我使用dotnet core 2.0和LinqKit.Microsoft.EntityFrameworkCore 1.1.10查看代码,可以假定
castCondition
变量的类型是
Expression
(与早期版本的
PredicateBuilder
一样)

但是如果是这种情况,那么
n.CastInfo.Any(castCondition)
甚至不应该编译(假设
CastInfo
是一个集合导航属性,那么编译器将点击
可枚举。任何需要
Func
,而不是
表达式的
)。这是怎么回事

在我看来,这是C#隐式运算符滥用的一个很好的例子。
PredicateBuilder.New
方法实际上返回一个名为的类,该类有许多方法模拟
Expression
,但更重要的是,它有
Expression
Func
的隐式转换。后者允许该类用于顶级
可枚举
/
可查询
方法,以替换相应的lambda func/表达式。但是,它还可以防止在表达式树中使用时出现编译时错误,就像在您的例子中一样-编译器会发出类似
n.CastInfo.Any((Func)castCondition)
的消息,这当然会在运行时导致异常

LinqKit
AsExpandable
方法的整个思想是允许通过自定义
Invoke
扩展方法“调用”表达式,然后在表达式树中“展开”。因此,在开始时,如果变量类型是
Expression
,则预期用途是:

_context.Name.AsExpandable().Where(n => n.CastInfo.Any(c => castCondition.Invoke(c)));

但由于前面解释的原因,现在无法编译。因此,您必须首先将其转换为
表达式感谢您的详细解释。我尝试了您的代码,但不幸的是,我收到了一个警告
无法翻译LINQ表达式“where u castCondition_0.Invoke([c]),它将在本地进行计算。
因此,在编译和运行时,该条件不会添加到SQL中,并且查询会选择所有行。你有什么建议吗?实际上你提到了
ExpressionStarter
可以转换为
Expression
。因此,这起作用
var castExpr=(表达式)castCondition;context.Name.AsExpandable().Where(n=>n.CastInfo.Any(castExpr.Compile()).Count()
;内联由于某些原因变量不起作用内联不起作用,因为“扩展器”无法识别
ExpressionStarter.Compile()
。听起来像是不完整的LinqKit作业:(啊,这就是让我留在这里的Q&A类型!(我有时想退出)。上面的建议对我也起了作用。我收到了另一个错误,暗示与async/await的组合不可能。在应用上述提示并删除await和To…async()之后,所有这些都很好。谢谢!
System.Linq.Expressions.Expression<Func<CastInfo,bool>> castExpression = (c => true);
if (movies != null && movies.Length > 0)
{
    castExpression = (c => movies.Contains(c.MovieId));
}
if (roleType > 0)
{
    var existingExpression = castExpression;
    castExpression = c => existingExpression.Invoke(c) && c.RoleId == roleType;
}
IQueryable<Name> result = _context.Name.AsExpandable().Where(n => n.CastInfo.Any(castExpression.Compile()));
return await result.OrderBy(n => n.Name1).Take(25).ToListAsync();
_context.Name.AsExpandable().Where(n => n.CastInfo.Any(c => castCondition.Invoke(c)));
Expression<Func<CastInfo, bool>> castPredicate = castCondition;
_context.Name.AsExpandable().Where(n => n.CastInfo.Any(c => castPredicate.Invoke(c)));
_context.Name.AsExpandable().Where(n => n.CastInfo.Any(castPredicate.Compile()));
using System;
using System.Linq.Expressions;

namespace LinqKit
{
    public static class Extensions
    {
        public static Expression<Func<T, bool>> ToExpression<T>(this ExpressionStarter<T> expr) => expr;
    }
}
var castPredicate = castCondition.ToExpression();
_context.Name.AsExpandable().Where(n => n.CastInfo.Any(c => castCondition.ToExpression().Invoke(c)));