gpt4 book ai didi

c# - 具有组和项目的 MongoDb C# 驱动程序使用 Aggregate() 查询给出异常

转载 作者:行者123 更新时间:2023-12-05 08:51:40 25 4
gpt4 key购买 nike

我正在开发使用 MongoDb 作为数据库和 .Net Core 3.0 作为框架的应用程序。为了从数据库中获取数据,我创建了一个 DbContext 类并使用 MongoDbAggregation() 功能。我无法通过适当的预测。以下是 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
}
}

要调用函数 GroupBy(),我必须传递过滤器、选择器和投影,但我无法构建适当的表达式。以下是数据模型和调用函数:

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

namespace Test
{
[BsonIgnoreExtraElements]
public class Employee
{
[BsonId]
[BsonElement("_id")]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId Id { get; set; }

[BsonElement("type")]
[JsonProperty("type")]
public string Type { get; set; }

[BsonElement("id")]
public string CustomerId { get; set; }

[BsonElement("name")]
public string CustomerName { get; set; }
}
}

我将 Customer Repository 中的 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
}
}

异常(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')"

最佳答案

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

员工类

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;

namespace Test
{
[BsonIgnoreExtraElements]
public class Employee
{
[BsonId]
[BsonElement("_id")]
[BsonRepresentation(BsonType.ObjectId)]
public ObjectId Id { get; set; }

[BsonElement("type")]
public string Type { get; set; }

[BsonElement("id")]
[BsonRepresentation(BsonType.String)] // to avoid manual conversion
public int CustomerId { get; set; }

[BsonElement("name")]
public string CustomerName { get; set; }
}
}

数据库上下文

using MongoDB.Driver;
using System.Linq;

namespace Test.DbContext
{
public class MongoDbContext
{
private readonly IMongoClient _mongoDbClient = null;

private readonly IMongoDatabase _mongoDb = null;

public MongoDbContext()
{
_mongoDbClient = new MongoClient("mongodb://localhost");
_mongoDb = _mongoDbClient.GetDatabase("test");
}

public IAggregateFluent<TDocument> Aggregate<TDocument>() =>
_mongoDb.GetCollection<TDocument>(nameof(TDocument)).Aggregate();

}
}

存储库

using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
using Test.DbContext;

namespace Test.Repositories
{
public class CustomerRepository
{
private static readonly MongoDbContext _dbContext = new MongoDbContext();

public List<dynamic> GetSpecificData()
{
var result = _dbContext.Aggregate<Employee>()
.Match(e => e.CustomerId == 11)
.Group(e => e.Type, g => new { Key = g.Key, Count = g.Count(), Average = g.Average(e => e.CustomerId) })
.ToList();

return result.Cast<dynamic>().ToList();
}
}
}

我还建议您不要将匿名类型转换为动态类型。因此,创建并使用另一个类(用于组结果)以保持类型安全。

我也可以推荐给你看看 library我已经写了它消除了编写你自己的 dbContext 的需要。

然后看看this启动模板项目以查看它的使用情况。

关于c# - 具有组和项目的 MongoDb C# 驱动程序使用 Aggregate() 查询给出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59046827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com