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
}
}