Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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# IMongoCollection<;T>;当我传入Func的谓词时抛出一个<;T、 布尔>;_C#_Mongodb_Asp.net Core_Mongodb .net Driver - Fatal编程技术网

C# IMongoCollection<;T>;当我传入Func的谓词时抛出一个<;T、 布尔>;

C# IMongoCollection<;T>;当我传入Func的谓词时抛出一个<;T、 布尔>;,c#,mongodb,asp.net-core,mongodb-.net-driver,C#,Mongodb,Asp.net Core,Mongodb .net Driver,我正在尝试对ASP.NET核心web控制器进行单元测试。下面是原始数据访问的情况: var-database=configuration.GetSection(“MongoDb:database”).Value; var mongoSettings=new MongoCollectionSettings(){AssignIdOnInsert=true}; var users=client.GetDatabase(database.GetCollection(“用户”,mongoSettings)

我正在尝试对ASP.NET核心web控制器进行单元测试。下面是原始数据访问的情况:

var-database=configuration.GetSection(“MongoDb:database”).Value;
var mongoSettings=new MongoCollectionSettings(){AssignIdOnInsert=true};
var users=client.GetDatabase(database.GetCollection(“用户”,mongoSettings);
var user=users.Find(u=>u.EmailAddress==EmailAddress).SingleOrDefault();
这个很好用。它不容易进行单元测试(
Find
不能用Moq进行模拟),我更喜欢一层间接层而不是数据访问,所以我尝试重构成一个存储库类,如下所示:

公共接口IRepository
{
T SingleOrDefault(Func谓词);
}
公共类MongoRepository:IRepository
{
// ...
公共T SingleOrDefault(Func谓词)
{
var objects=client.GetDatabase(this.databaseName).GetCollection(this.repositoryName,this.settings);
var toReturn=objects.Find(o=>predicate(o)==true);
回归回归;
}
}
当我将控制器更新为使用
MongoRepository
时,它会抛出:

var usersRepo=newmongorepository(this.configuration,this.client);
var user=usersRepo.SingleOrDefault(u=>u.EmailAddress==EmailAddress);
具体地说,在存储库代码中,
objects.Find(o=>predicate(o)==true)
引发异常:
MongoDB.Driver.dll中发生了类型为“System.InvalidOperationException”的异常,但未在用户代码中处理:“不支持调用(值(System.Func
2[AutoDungeons.Web.Models.user,System.Boolean]),{document。”`

我不知道如何解决这个问题。我怀疑谓词
Func
的定义不正确,因为如果我只调用
objects.Find(o=>true)
,它将返回第一个对象,而不会出现任何问题

下面是完整的异常堆栈

An exception of type 'System.InvalidOperationException' occurred in MongoDB.Driver.dll but was not handled in user code: 'Invoke(value(System.Func`2[AutoDungeoners.Web.Models.User,System.Boolean]), {document}) is not supported.'
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.GetFieldExpression(Expression expression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(Expression variableExpression, ExpressionType operatorType, ConstantExpression constantExpression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(BinaryExpression binaryExpression)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(Expression node, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](Expression`1 predicate, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
   at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
   at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass41_0`1.<FindSync>b__0(IClientSessionHandle session)
   at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
   at MongoDB.Driver.MongoCollectionImpl`1.FindSync[TProjection](FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
   at MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken cancellationToken)
   at MongoDB.Driver.IAsyncCursorSourceExtensions.SingleOrDefault[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)
   at MongoDB.Driver.IFindFluentExtensions.SingleOrDefault[TDocument,TProjection](IFindFluent`2 find, CancellationToken cancellationToken)

MongoDB.Driver.dll中发生类型为“System.InvalidOperationException”的异常,但未在用户代码中处理:“不支持调用(值(System.Func`2[AutoDungeons.Web.Models.user,System.Boolean]),{document}。”
位于MongoDB.Driver.Linq.Translators.PredicateTranslator.GetFieldExpression(表达式)
在MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(表达式变量表达式,表达式类型运算符类型,常量表达式)
位于MongoDB.Driver.Linq.Translators.PredicateTranslator.TranslateComparison(二进制表达式二进制表达式)
位于MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(表达式节点)
位于MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate(表达式节点,IBMSOnSerializerRegistry serializerRegistry)
在MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](表达式`1谓词,IBMONSerializer`1参数序列化器,IBMONSerializerRegistry serializerRegistry)
位于MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBMOSonSerializer`1 documentSerializer,IBMOSonSerializerRegistry serializerRegistry)
在MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[Tproject](过滤器定义`1过滤器,FindOperations`2选项)
在MongoDB.Driver.MongoCollectionImpl`1.FindSync[tProject](IClientSessionHandle会话,FilterDefinition`1筛选器,FindOptions`2选项,CancellationToken CancellationToken)
在MongoDB.Driver.MongoCollectionImpl`1.c__显示Class41_0`1.b__0(IClientSessionHandle会话)
在MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 Func,CancellationToken CancellationToken)
在MongoDB.Driver.MongoCollectionImpl`1.FindSync[tProject](FilterDefinition`1过滤器,FindOptions`2选项,CancellationToken CancellationToken)
在MongoDB.Driver.FindFluent`2.ToCursor(CancellationToken CancellationToken)
在MongoDB.Driver.IAsyncCursorSourceExtensions.SingleOrDefault[TDocument](IAsyncCursorSource`1 source,CancellationToken CancellationToken)
在MongoDB.Driver.IFindFluentExtensions.SingleOrDefault[TDocument,tProject](IFindFluent`2查找,取消令牌取消令牌)

这里可以使用的
查找(…)
方法的唯一实现是:


请记住,这只适用于那些可以翻译成MongoDB查询语言的表达式
u=>u.EmailAddress==EmailAddress
看起来不错。

EmailAddress的类型是什么?出于好奇,如果您尝试简化为
var toReturn=objects.Find(predicate).SingleOrDefault()我不知道它是如何生成查询的,但我想知道它是否不喜欢您调用谓词而不仅仅是作为参数提供它。@Scottannen
EmailAddress
只是一个字符串。我认为
objects.Find(predicate)
无法编译,因为它试图将
System.Something.Expression>
转换为
Func
。在传入
Func
之前,如何将其转换为表达式@这导致了同样的例外。你的解释是有道理的。除了必须传入
Func
而不是谓词的问题之外,此代码不编译-
谓词(o)
不适用于
Func
。另外,请参见上面Scott的评论:转换为
表达式
会引发相同的异常。@nightblade9这是我的错,对不起-不要运行谓词,只传递表达式即可。修改了我的答案哇,真的行了!我有点惊讶(我根据注释做了类似的事情——只是在内部将
Func
转换为
Expression
,然后抛出)。非常感谢!
public static IFindFluent<TDocument, TDocument> Find<TDocument>(this IMongoCollection<TDocument> collection, Expression<Func<TDocument, bool>> filter, FindOptions options = null)
public T SingleOrDefault(Expression<Func<T, bool>> predicate)
{
    var objects = client.GetDatabase(this.databaseName).GetCollection<T>(this.repositoryName, this.settings);
    var toReturn = objects.Find(predicate).SingleOrDefault();
    return toReturn;
}