【发布时间】:2018-10-19 19:28:42
【问题描述】:
我试图从集合中检索数据,如下所示
var results = await repository.FindAsync(GetFilter(ids));
private System.Linq.Expressions.Expression<Func<SomeEntity, bool>> GetFilter(IEnumerable<long> someIds)
{
return x => someIds.Contains(x.Id) &&
x.subscriptions
.Where(s => s.servicePlans.Contains((int)ServicePlanEnum.Service1)).Any();
}
但我得到了以下异常
System.InvalidCastException:无法将“System.Linq.Expressions.ConstantExpression”类型的对象转换为“System.Linq.Expressions.LambdaExpression”类型。
我哪里错了?
编辑:
订阅对象如下:
subscription :
{
prop1 : string,
prop2 : int,
servicePlans : int[]
}
FindAsync 定义:
protected IMongoCollection<TEntity> Collection => database.GetCollection<TEntity>(collectionName);
private IFindFluent<TEntity, TEntity> Find(Expression<Func<TEntity, bool>> predicate) => Collection.Find(predicate);
public virtual async Task<ICollection<TEntity>> FindAsync(Expression<Func<TEntity, bool>> predicate, SortOrder<TEntity>[] sort = null, int? page = null, int? limit = null)
{
var query = Find(predicate);
return await
query
.Skip(page == null && limit == null ? null : (page - 1) * limit)
.Limit(limit)
.Sort(sort)
.ToListAsync();
}
错误是由以下情况引起的
x.subscriptions.Where(s => s.servicePlans.Contains((int)ServicePlanEnum.Service1)).Any();
编辑:
堆栈跟踪:
无法将“System.Linq.Expressions.ConstantExpression”类型的对象转换为“System.Linq.Expressions.LambdaExpression”类型。 System.InvalidCastException:无法将“System.Linq.Expressions.ConstantExpression”类型的对象转换为“System.Linq.Expressions.LambdaExpression”类型。 在 MongoDB.Driver.Linq.ExpressionHelper.GetLambda(表达式节点) 在 MongoDB.Driver.Linq.Processors.EmbeddedPipeline.MethodCallBinders.AnyBinder.Bind(PipelineExpression 管道,EmbeddedPipelineBindingContext bindingContext,MethodCallExpression 节点,IEnumerable
1 arguments) at MongoDB.Driver.Linq.Processors.MethodInfoMethodCallBinder1.Bind(PipelineExpression 管道,TBindingContext bindingContext,MethodCallExpression 节点,IEnumerable1 arguments) at MongoDB.Driver.Linq.Processors.CompositeMethodCallBinder1.Bind (PipelineExpression管道,TBindingContext bindingContext,MethodCallExpression节点,IEnumerable1 arguments) at MongoDB.Driver.Linq.Processors.PipelineBinderBase1.BindMethodCall(MethodCallExpression节点) 在 MongoDB.Driver.Linq.Processors.EmbeddedPipeline.EmbeddedPipelineBinder.Bind(表达式节点,IBindingContext 父级) 在 MongoDB.Driver.Linq.Processors.SerializationBinder.VisitMethodCall(MethodCallExpression 节点) 在 System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor 访问者) 在 MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(表达式节点) 在 System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression 节点) 在 MongoDB.Driver.Linq.Processors.SerializationBinder.VisitBinary(BinaryExpression 节点) 在 System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor 访问者) 在 MongoDB.Driver.Linq.Processors.SerializationBinder.Visit(表达式节点) 在 MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](Expression1 predicate, IBsonSerializer1 parameterSerializer, IBsonSerializerRegistry serializerRegistry) 在 MongoDB.Driver.MongoCollectionImpl1.CreateFindOperation[TProjection](FilterDefinition1 过滤器,FindOptions2 options) at MongoDB.Driver.MongoCollectionImpl1.FindAsync[TProjection](IClientSessionHandle 会话,FilterDefinition1 filter, FindOptions2 选项,CancellationToken cancelToken) 在 MongoDB.Driver.MongoCollectionImpl1.<>c__DisplayClass43_01.b__0(IClientSessionHandle 会话) 在 MongoDB.Driver.MongoCollectionImpl1.UsingImplicitSessionAsync[TResult](Func2 funcAsync, CancellationToken cancelToken) 在 ...\Infastructure\Repositories\MongoRepository.cs:line 中的 MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource1 source, CancellationToken cancellationToken) at ...Repository.MongoRepository2.FindAsync(Expression1 predicate, SortOrder1[] 排序,Nullable1 page, Nullable1 限制) 71 在 ...Controllers.AccountController.GetCliniciansByClinicAsync(String ClinicId, CancellationToken cancelToken) 在 ...\Controllers\AccountController.cs:line 94 在 Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper 映射器,ObjectMethodExecutor 执行器,对象控制器,对象 [] 参数) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() 在 Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()
【问题讨论】:
-
不要在表达式中进行强制转换,将其存储在变量中 (int)SomeEnum.Member
-
FindAsync()中的参数类型是什么? -
@johnny5 我没听懂你说的,(int)SomeEnum.Member 是一个常量(枚举)。
-
我怀疑 Gert Arnold 是正确的。顺便说一句,我不希望用户代码出现像您所写的那样的异常。我的猜测是,查询重写器中很可能存在一些问题。或者,缺陷可能在于表达式树生成本身,呃,这会成为我的错。但我会从调用堆栈开始,看看哪里出了问题。
-
(如果您不是 100% 清楚“plebbery”是什么,那么在网络上搜索“MongoDB plebbery”是一种在编译时浪费一点时间的有趣方式。当我注意到这一点时我在 Coverity 工作。)