MongoDb C#驱动程序,使用Aggregate()查询的组和项目出现异常

MongoDb C#驱动程序,使用Aggregate()查询的组和项目出现异常,c#,mongodb,linq,aggregation-framework,C#,Mongodb,Linq,Aggregation Framework,我正在开发一个应用程序,它使用MongoDb作为数据库,.netcore3.0作为框架。为了从数据库中获取数据,我创建了一个DbContext类,并使用MongoDb的Aggregation()功能。我无法通过适当的投影。以下是DbContext.cs using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using

我正在开发一个应用程序,它使用
MongoDb
作为数据库,
.netcore3.0
作为框架。为了从数据库中获取数据,我创建了一个
DbContext
类,并使用
MongoDb
Aggregation()
功能。我无法通过适当的投影。以下是
DbContext.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using Microsoft.Extensions.Options;
    using MongoDB.Driver;

    namespace Test.DbContext
    {
        /// <summary>
        /// Standard CRUD Operations with MongoDb  
        /// </summary>
        public class MongoDbContext   
        {
            #region Properties
            private readonly IMongoClient _mongoDbClient = null;

            private readonly IMongoDatabase _mongoDb = null;
            #endregion

            #region Constructor
            public MongoDbContext(IOptions<MongoSetting> mongoConfigs)
            {
                _mongoDbClient = new MongoClient(mongoConfigs.Value.ConnectionString);
                _mongoDb = _mongoDbClient.GetDatabase(mongoConfigs.Value.DatabaseName);
            }
            #endregion

            #region Grouping
            public IList<TProjection> GroupBy<TDocument, TGroupKey, TProjection> 
            (FilterDefinition<TDocument> filter, 
             Expression<Func<TDocument, TGroupKey>> selector, 
             Expression<Func<IGrouping<TGroupKey, TDocument>, TProjection>> projection){
                   return _mongoDb.GetCollection<TDocument>("collectionName").Aggregate().Match(filter).Group(selector, projection).ToList();
               }   
            #endregion
        }
    }
我将客户存储库中的dbContext称为:

using System;
using System.Linq.Expressions;
using MongoDB.Driver;

namespace Test.Repositories
{
    public class CustomerRepository : ICustomerRepository
    {
        #region Properties
        private readonly IMongoDbContext _dbContext = null;
        #endregion

        #region Constructor
        public CustomerRepository(IMongoDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        #endregion

        #region Methods
        public EmployeeCollection GetSpecificData()
        {

            Expression<Func<Employee, dynamic>> filter = x => x.Employee.CustomerId == "11";
            Expression<Func<Employee, dynamic>> selector = x => new { typeName = x.Employee.Type };
            Expression<Func<IGrouping<dynamic, Employee>, dynamic>> projection = x => new
            {
                Key = x.Key,
                count = x.Count(),
                avgValue = x.Average(x => Convert.ToInt32(x.Employee.CustomerId))
            };


            var result = _dbContext.GroupBy<Employee, dynamic, dynamic>(filter, selector, projection);

            // Giving exception
            // "Value type of serializer is <>f__AnonymousType0`1[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, 
            //PublicKeyToken=7cec85d7bea7798e]] and does not match member type System.Object. (Parameter 'serializer')"
        }
        #endregion
    }
}
使用系统;
使用System.Linq.Expressions;
使用MongoDB.Driver;
名称空间测试.存储库
{
公共类CustomerRepository:ICCustomerRepository
{
#区域属性
私有只读IMongoDbContext _dbContext=null;
#端区
#区域构造函数
公共CustomerRepository(IMongoDbContext)
{
_dbContext=dbContext;
}
#端区
#区域方法
公共EmployeeCollection GetSpecificData()
{
表达式筛选器=x=>x.Employee.CustomerId==“11”;
表达式选择器=x=>new{typeName=x.Employee.Type};
表达式投影=x=>new
{
Key=x.Key,
count=x.count(),
avgValue=x.Average(x=>Convert.ToInt32(x.Employee.CustomerId))
};
var result=_dbContext.GroupBy(过滤器、选择器、投影);
//破例
//序列化程序的值类型为f__AnonymousType0`1[[System.String,System.Private.CoreLib,Version=4.0.0.0,Culture=neutral,
//PublicKeyToken=7cec85d7bea7798e]]并且与成员类型System.Object不匹配。(参数“序列化程序”)
}
#端区
}
}
例外情况:

“序列化程序的值类型为f__AnonymousType0`1[[System.String, System.Private.CoreLib,版本=4.0.0.0,区域性=中性, PublicKeyToken=7cec85d7bea7798e]]并且与成员类型不匹配 System.Object。(参数“序列化程序”)


我认为你想做的事不可行。作为替代方案,我可以建议从dbContext中公开
.Aggregate()
,并从repo中进行查询,如下所示

员工类别

使用MongoDB.Bson;
使用MongoDB.Bson.Serialization.Attributes;
名称空间测试
{
[BsonIgnoreExtraElements]
公营雇员
{
[BsonId]
[b单一元素(“_id”)]
[BsonRepresentation(BsonType.ObjectId)]
公共对象Id{get;set;}
[b单一元素(“类型”)]
公共字符串类型{get;set;}
[b单一元素(“id”)]
[BsonRepresentation(BsonType.String)]//避免手动转换
public int CustomerId{get;set;}
[b单一元素(“名称”)]
公共字符串CustomerName{get;set;}
}
}
DB上下文

使用MongoDB.Driver;
使用System.Linq;
命名空间Test.DbContext
{
公共类MongoDbContext
{
私有只读IMongoClient _mongoDbClient=null;
私有只读IMongoDatabase_mongoDb=null;
公共MongoDbContext()
{
_mongoDbClient=新的MongoClient(“mongodb://localhost");
_mongoDb=_mongoDbClient.GetDatabase(“测试”);
}
公共IAggregateFluent聚合()=>
_mongoDb.GetCollection(nameof(TDocument)).Aggregate();
}
}
存储库

使用MongoDB.Driver;
使用System.Collections.Generic;
使用System.Linq;
使用Test.DbContext;
名称空间测试.存储库
{
公共类CustomerRepository
{
私有静态只读MongoDbContext _dbContext=new MongoDbContext();
公共列表GetSpecificData()
{
var result=_dbContext.Aggregate()
.Match(e=>e.CustomerId==11)
.Group(e=>e.Type,g=>new{Key=g.Key,Count=g.Count(),Average=g.Average(e=>e.CustomerId)})
.ToList();
返回result.Cast().ToList();
}
}
}
我还建议您不要将匿名类型强制转换为动态类型。因此,创建并使用另一个类(用于组结果)来保持类型安全性

我还可以建议您看一看我写的一本书,它消除了编写自己的dbContext的需要

然后看看starter模板项目,看看它在使用中

using System;
using System.Linq.Expressions;
using MongoDB.Driver;

namespace Test.Repositories
{
    public class CustomerRepository : ICustomerRepository
    {
        #region Properties
        private readonly IMongoDbContext _dbContext = null;
        #endregion

        #region Constructor
        public CustomerRepository(IMongoDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        #endregion

        #region Methods
        public EmployeeCollection GetSpecificData()
        {

            Expression<Func<Employee, dynamic>> filter = x => x.Employee.CustomerId == "11";
            Expression<Func<Employee, dynamic>> selector = x => new { typeName = x.Employee.Type };
            Expression<Func<IGrouping<dynamic, Employee>, dynamic>> projection = x => new
            {
                Key = x.Key,
                count = x.Count(),
                avgValue = x.Average(x => Convert.ToInt32(x.Employee.CustomerId))
            };


            var result = _dbContext.GroupBy<Employee, dynamic, dynamic>(filter, selector, projection);

            // Giving exception
            // "Value type of serializer is <>f__AnonymousType0`1[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, 
            //PublicKeyToken=7cec85d7bea7798e]] and does not match member type System.Object. (Parameter 'serializer')"
        }
        #endregion
    }
}