Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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#Mongo DB驱动程序-方法调用不起作用的表达式_C#_Database_Mongodb_Linq Expressions_Mongodb Csharp 2.0 - Fatal编程技术网

C#Mongo DB驱动程序-方法调用不起作用的表达式

C#Mongo DB驱动程序-方法调用不起作用的表达式,c#,database,mongodb,linq-expressions,mongodb-csharp-2.0,C#,Database,Mongodb,Linq Expressions,Mongodb Csharp 2.0,我试图通过发送一个表达式(C#mongo驱动程序版本2.7.3)来查询一些数据并投影到一个属性较少的类。 我试图理解为什么一个特定的表达式失败。 失败极大地限制了用户编写公共投影,并迫使用户在每次调用中内联编写投影。 这是一个简化的示例: private IMongoCollection<MyOriginalClass> _collection; class MyOriginalClass // imagine this class has many more properties

我试图通过发送一个表达式(C#mongo驱动程序版本2.7.3)来查询一些数据并投影到一个属性较少的类。 我试图理解为什么一个特定的表达式失败。 失败极大地限制了用户编写公共投影,并迫使用户在每次调用中内联编写投影。 这是一个简化的示例:

private IMongoCollection<MyOriginalClass> _collection;

class MyOriginalClass // imagine this class has many more properties
{
  public int ID { get; set; }
}

class MyProjectedClass
{
  public int ID { get; set; }
}

void DoWork()
{
  var data1 = GetData(lib => new MyProjectedClass { ID = lib.ID }); // succeeds
  var data2 = GetData(lib => ToProjected(lib)); // Fails in mongo driver: Index was out of range. Must be non-negative and less than the size of the collection.Parameter name: index
}

IEnumerable<MyProjectedClass> GetData(Expression<Func<MyOriginalClass, MyProjectedClass>> projection)
{       
  return _collection
      .Aggregate()
      .Project(Builders<MyOriginalClass>.Projection.Expression(projection))
      .ToList();
}

MyProjectedClass ToProjected(MyOriginalClass orig)
{
    return new MyProjectedClass {ID = orig.ID};
}
私人IMongoCollection\u collection;
类MyOriginalClass//想象这个类有更多的属性
{
公共int ID{get;set;}
}
类MyProjectedClass
{
公共int ID{get;set;}
}
无效销钉()
{
var data1=GetData(lib=>newmyprojectedclass{ID=lib.ID});//成功
var data2=GetData(lib=>ToProjected(lib));//在mongo驱动程序中失败:索引超出范围。必须为非负且小于集合的大小。参数名称:Index
}
IEnumerable GetData(表达式投影)
{       
返回集合
.Aggregate()
.项目(建筑商.投影.表达式(投影))
.ToList();
}
MyProjectedClass到Projected(MyOriginalClass原始)
{
返回新的MyProjectedClass{ID=orig.ID};
}
首次(成功)使用是一个表达式,mongo驱动程序可以在运行时查看该表达式,从而知道ID=lib.ID。特别是这里

例如,Visual Studio允许在调试器下进行表达式可视化,对于第一个调试器,它显示:

.Lambda #Lambda1<System.Func`2[ConsoleApp1.Program+MyOriginalClass,ConsoleApp1.Program+MyProjectedClass]>(ConsoleApp1.Program+MyOriginalClass $lib)
{
    .New ConsoleApp1.Program+MyProjectedClass(){
        ID = $lib.ID
    }
}

请熟悉,但第二个仍然是表达式,而不是Func(它未编译)。没错。我已经更新了我的答案,使其更加具体,这样编译表达式(Func)和MethodCallExpression之间就没有区别了?MethodCallExpression无法被遍历?这并没有什么区别,MethodCallExpression只是调用编译后的代码,因为表达式树非常浅,在运行时提供的信息很少。相比之下,NewExpression可能是一个更大的表达式树,包含更多信息。是的,MethodCallExpression不能被遍历(没有反编译)
.Lambda #Lambda1<System.Func`2[ConsoleApp1.Program+MyOriginalClass,ConsoleApp1.Program+MyProjectedClass]>(ConsoleApp1.Program+MyOriginalClass $lib)
{
    .Call ConsoleApp1.Program.ToProjected($lib)
}
Expression<Func<MyOriginalClass, MyProjectedClass>> ToProjected()
{
    return lib => new MyProjectedClass { ID = lib.ID };
}
var data2 = GetData(ToProjected());