https://www.thecodebuzz.com/exception-filters-in-net-core/
https://www.mongodb.com/docs/drivers/csharp/
https://www.mongodb.com/developer/languages/csharp/create-restful-api-dotnet-core-mongodb/
- 安装依赖的包
- 定义服务接口
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MongoDBHelper.Helper
{
public interface IMongoDB<T> where T : class
{
Task InsertOne(T document);
Task InsertMany(List<T> documents);
Task<long> BulkInsert(List<T> documents);
Task<UpdateResult> UpdateOne(string name, string id);
Task<UpdateResult> UpdateMultiFields(T document, string id);
Task Inc(string id);
Task<List<T>> GetAll();
Task<T> GetOneByID(string id);
}
}
- 定义实体类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
namespace MongoDBHelper.Model
{
public class Person
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
//我们系统里这个字段名称是Age。但是MongoDB存的是age
[BsonElement("age")]
[JsonPropertyName("age")]
public int Age { get; set; }
[BsonElement("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
//系统以及MongoDB里都是address
public string address { get; set; }
//这个字段不会存到MongoDB中
[BsonIgnore]
public string IgnoreField { get; set; }
}
}
- 定义helper 类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MongoDB.Driver;
using Microsoft.Extensions.Options;
using MongoDBHelper.Model;
using MongoDB.Bson;
namespace MongoDBHelper.Helper
{
public class MongoDBTools<T>: IMongoDB<T> where T : Person
{
public readonly IMongoCollection<T> mongoCollection;
public IOptionsSnapshot<Config> _config;
public MongoDBTools(IOptionsSnapshot<Config> config)
{
_config = config;
MongoClient client = new MongoClient(config.Value.connectstring);
var database = client.GetDatabase(config.Value.database);
mongoCollection = database.GetCollection<T>(config.Value.collection);
}
public Task InsertOne(T document)
{
return mongoCollection.InsertOneAsync(document);
}
public Task InsertMany(List<T> documents)
{
return mongoCollection.InsertManyAsync(documents,new InsertManyOptions() { IsOrdered=false});
}
//批量插入,忽略排序
//默认是不忽略排序的,以这种方式插入数据,假如中间的失败了,则以后的也不再插入
//取消默认排序后,即使中间又失败的数据,后续数据也会继续插入
public async Task<long> BulkInsert(List<T> documents)
{
try
{
List<WriteModel<T>> values = new List<WriteModel<T>>();
foreach (var item in documents)
{
values.Add(new InsertOneModel<T>(item));
}
return mongoCollection.BulkWriteAsync(documents.Select(x => new InsertOneModel<T>(x)).ToList(), new BulkWriteOptions() { IsOrdered = true }).Result.InsertedCount;
}
catch (Exception)
{
Exception exception = new Exception("批量插入失败");
throw exception;
}
}
public Task<UpdateResult> UpdateOne(string name,string id)
{
UpdateDefinition<T> update = Builders<T>.Update.AddToSet<string>("name", name);
return mongoCollection.UpdateOneAsync(Builders<T>.Filter.Eq("Id",id), update);
}
public Task<UpdateResult> UpdateMultiFields(T document,string id)
{
UpdateDefinition<T> updateDefinition = Builders<T>.Update.Set(x => x.Name, document.Name).Set(x=>x.Age,document.Age);
return mongoCollection.UpdateOneAsync(Builders<T>.Filter.Eq("Id", id), updateDefinition);
}
public Task Inc(string id)
{
FilterDefinition<T> filterDefinition = Builders<T>.Filter.Eq("Id", id);
UpdateDefinition<T> updateDefinition = Builders<T>.Update.Inc("Age", 1);
return mongoCollection.UpdateOneAsync(filterDefinition, updateDefinition);
}
public async Task<List<T>> GetAll()
{
return await mongoCollection.FindSync(new BsonDocument()).ToListAsync();
}
public Task<T> GetOneByID(string id)
{
return mongoCollection.Find(Builders<T>.Filter.Eq("Id",id)).FirstOrDefaultAsync();
}
}
}
- 定义controller
using Microsoft.AspNetCore.Mvc;
using MongoDBHelper.Helper;
using MongoDBHelper.Model;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace CoreMongoDB.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class MongoDB : ControllerBase
{
public readonly IMongoDB<Person> _mongoDBTools;
public MongoDB(IMongoDB<Person> mongoDBTools)
{
_mongoDBTools = mongoDBTools;
}
[HttpPost]
public async Task<bool> InsertOne([FromBody] Person person)
{
await _mongoDBTools.InsertOne(person);
return true;
}
[HttpGet]
public Task<List<Person>> ListAll()
{
return _mongoDBTools.GetAll();
}
[HttpGet]
public Task<Person> GetByID([FromQuery] string id)
{
return _mongoDBTools.GetOneByID(id);
}
[HttpPost]
public async Task<long> BulkInsert([FromBody] List<Person> persons)
{
return await _mongoDBTools.BulkInsert(persons);
}
[HttpPut]
public long UpdateMultiFields([FromBody] Person person,[FromQuery] string id)
{
return _mongoDBTools.UpdateMultiFields(person, id).Result.ModifiedCount;
}
}
}
- 定义全局异常filter
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace CoreMongoDB.Exception
{
public class ExceptionHandler : IAsyncExceptionFilter
{
public Task OnExceptionAsync(ExceptionContext context)
{
string message = context.Exception.Message;
ObjectResult objectResult = new ObjectResult(new { code = 500, msg = message });
//Logs your technical exception with stack trace below
context.Result = objectResult;
return Task.CompletedTask;
}
}
}
- 依赖注入
builder.Services.Configure<Config>(
builder.Configuration.GetSection("MongoDBConfig"));
builder.Services.AddScoped<Config>();
builder.Services.AddScoped(typeof(IMongoDB<>),typeof(MongoDBTools<>));
builder.Services.Configure<MvcOptions>(opt =>
{
opt.Filters.Add<ExceptionHandler>();
});