Asp.Net Core MongoDB
废话不说直接上代码;
using MongoDB.Bson.Serialization.Attributes; namespace XL.Core.MongoDB { public interface IEntity<TKey> { /// <summary> /// 主键 /// </summary> [BsonId] TKey Id { get; set; } } }
[BsonIgnoreExtraElements(Inherited = true)] public abstract class Entity : IEntity<string> { /// <summary> /// 主键 /// </summary> [BsonRepresentation(BsonType.ObjectId)] public virtual string Id { get; set; } }
public interface IRepository<T, in TKey> : IQueryable<T> where T : IEntity<TKey> { #region Fileds /// <summary> /// MongoDB表 /// </summary> IMongoCollection<T> DbSet { get; } /// <summary> /// MongoDB库 /// </summary> IMongoDatabase DbContext { get; } #endregion #region Find /// <summary> /// 根据主键获取对象 /// </summary> /// <param name="id"></param> /// <returns></returns> T GetById(TKey id); /// <summary> /// 获取对象 /// </summary> /// <param name="predicate"></param> /// <returns></returns> IEnumerable<T> Get(Expression<Func<T, bool>> predicate); /// <summary> /// 获取对象 /// </summary> /// <param name="predicate"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); #endregion #region Insert /// <summary> /// 插入文档 /// </summary> /// <param name="entity"></param> /// <returns></returns> T Insert(T entity); /// <summary> /// 异步插入文档 /// </summary> /// <param name="entity"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task InsertAsync(T entity, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// Adds the new entities in the repository. /// </summary> /// <param name="entities">The entities of type T.</param> void Insert(IEnumerable<T> entities); /// <summary> /// 插入文档 /// </summary> /// <param name="entities"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task InsertAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default(CancellationToken)); #endregion #region Update /// <summary> /// 更新文档 /// </summary> /// <param name="entity"></param> /// <returns></returns> UpdateResult Update(T entity); /// <summary> /// 异步更新文档 /// </summary> /// <param name="entity"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<UpdateResult> UpdateAsync(T entity, CancellationToken cancellationToken = default(CancellationToken)); #endregion #region Delete /// <summary> /// 根据主键ID /// </summary> /// <param name="id"></param> /// <returns></returns> T Delete(TKey id); /// <summary> /// 异步根据ID删除文档 /// </summary> /// <param name="id"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<T> DeleteAsync(TKey id, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// 异步删除 /// </summary> /// <param name="predicate"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<DeleteResult> DeleteAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = default(CancellationToken)); /// <summary> /// 删除 /// </summary> /// <param name="predicate"></param> /// <returns></returns> DeleteResult Delete(Expression<Func<T, bool>> predicate); #endregion #region Other /// <summary> /// 计数 /// </summary> /// <param name="predicate"></param> /// <returns></returns> long Count(Expression<Func<T, bool>> predicate); /// <summary> /// 计数 /// </summary> /// <param name="predicate"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<long> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = new CancellationToken()); /// <summary> /// 是否存在 /// </summary> /// <param name="predicate"></param> /// <returns></returns> bool Exists(Expression<Func<T, bool>> predicate); #endregion #region Query /// <summary> /// 分页 /// 注:只适合单属性排序 /// </summary> /// <param name="predicate"></param> /// <param name="sortBy"></param> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <returns></returns> IEnumerable<T> Paged(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortBy, int pageSize, int pageIndex = 1); /// <summary> /// /// </summary> /// <param name="predicate"></param> /// <param name="sortBy"></param> /// <param name="pageSize"></param> /// <param name="pageIndex"></param> /// <param name="cancellationToken"></param> /// <returns></returns> Task<List<T>> PagedAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortBy, int pageSize, int pageIndex = 1, CancellationToken cancellationToken = new CancellationToken()); #endregion } public interface IRepository<T> : IRepository<T, string> where T : IEntity<string> { }
public class MongoRepository<T> : IRepository<T> where T : IEntity<string> { #region Constructor protected MongoRepository(IMongoCollection<T> collection) { DbSet = collection; DbContext = collection.Database; } #endregion public IEnumerator<T> GetEnumerator() { return DbSet.AsQueryable().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #region 字段 public Type ElementType => DbSet.AsQueryable().ElementType; public Expression Expression => DbSet.AsQueryable().Expression; public IQueryProvider Provider => DbSet.AsQueryable().Provider; public IMongoCollection<T> DbSet { get; } public IMongoDatabase DbContext { get; } #endregion #region Find public T GetById(string id) { return Get(a => a.Id.Equals(id)).FirstOrDefault(); } public IEnumerable<T> Get(Expression<Func<T, bool>> predicate) { return DbSet.FindSync(predicate).Current; } public async Task<IEnumerable<T>> GetAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = new CancellationToken()) { var task = await DbSet.FindAsync(predicate, null, cancellationToken); return task.Current; } #endregion #region Insert public T Insert(T entity) { DbSet.InsertOne(entity); return entity; } public Task InsertAsync(T entity, CancellationToken cancellationToken = new CancellationToken()) { return DbSet.InsertOneAsync(entity, null, cancellationToken); } public void Insert(IEnumerable<T> entities) { DbSet.InsertMany(entities); } public Task InsertAsync(IEnumerable<T> entities, CancellationToken cancellationToken = new CancellationToken()) { return DbSet.InsertManyAsync(entities, null, cancellationToken); } #endregion #region Update public UpdateResult Update(T entity) { var doc = entity.ToBsonDocument(); return DbSet.UpdateOne(Builders<T>.Filter.Eq(e => e.Id, entity.Id), new BsonDocumentUpdateDefinition<T>(doc)); } public Task<UpdateResult> UpdateAsync(T entity, CancellationToken cancellationToken = new CancellationToken()) { var doc = entity.ToBsonDocument(); return DbSet.UpdateOneAsync(Builders<T>.Filter.Eq(e => e.Id, entity.Id), new BsonDocumentUpdateDefinition<T>(doc), cancellationToken: cancellationToken); } #endregion #region Delete public T Delete(string id) { return DbSet.FindOneAndDelete(a => a.Id.Equals(id)); } public Task<T> DeleteAsync(string id, CancellationToken cancellationToken = new CancellationToken()) { return DbSet.FindOneAndDeleteAsync(a => a.Id.Equals(id), null, cancellationToken); } public Task<DeleteResult> DeleteAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = new CancellationToken()) { return DbSet.DeleteManyAsync(predicate, cancellationToken); } public DeleteResult Delete(Expression<Func<T, bool>> predicate) { return DbSet.DeleteMany(predicate); } #endregion #region Other public long Count(Expression<Func<T, bool>> predicate) { return DbSet.Count(predicate); } public Task<long> CountAsync(Expression<Func<T, bool>> predicate, CancellationToken cancellationToken = new CancellationToken()) { return DbSet.CountAsync(predicate, null, cancellationToken); } public bool Exists(Expression<Func<T, bool>> predicate) { return Get(predicate).Any(); } #endregion #region Page public IEnumerable<T> Paged(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortBy, int pageSize, int pageIndex = 1) { var sort = Builders<T>.Sort.Descending(sortBy); return DbSet.Find(predicate).Sort(sort).Skip(pageSize * pageIndex - 1).Limit(pageSize).ToList(); } public Task<List<T>> PagedAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> sortBy, int pageSize, int pageIndex = 1, CancellationToken cancellationToken = new CancellationToken()) { return Task.Run(() => { var sort = Builders<T>.Sort.Descending(sortBy); return DbSet.Find(predicate).Sort(sort).Skip(pageSize * pageIndex - 1).Limit(pageSize).ToList(); }, cancellationToken); } #endregion #region Helper /// <summary> /// 获取类型的所有属性信息 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="select"></param> /// <returns></returns> private PropertyInfo[] GetPropertyInfos<TProperty>(Expression<Func<T, TProperty>> select) { var body = select.Body; switch (body.NodeType) { case ExpressionType.Parameter: var parameterExpression = body as ParameterExpression; if (parameterExpression != null) return parameterExpression.Type.GetProperties(); break; case ExpressionType.New: var newExpression = body as NewExpression; if (newExpression != null) return newExpression.Members.Select(m => m as PropertyInfo).ToArray(); break; } return null; } #endregion }
使用如下:
public class MongoDBSetting { public string DataBase { get; set; } public string UserName { get; set; } public string Password { get; set; } public List<MongoServers> Services { get; set; } } public class MongoServers { public string Host { get; set; } public int Port { get; set; } = 27017; }
public class LogsContext { private readonly IMongoDatabase _db; public LogsContext(IOptions<MongoDBSetting> options) { var permissionSystem = MongoCredential.CreateCredential(options.Value.DataBase, options.Value.UserName, options.Value.Password); var services = new List<MongoServerAddress>(); foreach (var item in options.Value.Services) { services.Add(new MongoServerAddress(item.Host, item.Port)); } var settings = new MongoClientSettings { Credentials = new[] {permissionSystem}, Servers = services }; var _mongoClient = new MongoClient(settings); _db = _mongoClient.GetDatabase(options.Value.DataBase); } public IMongoCollection<ErrorLogs> ErrorLog => _db.GetCollection<ErrorLogs>("Error"); public IMongoCollection<ErrorLogs> WarningLog => _db.GetCollection<ErrorLogs>("Warning"); }
public static IServiceCollection UserMongoLog(this IServiceCollection services, IConfigurationSection configurationSection) { services.Configure<MongoDBSetting>(configurationSection); services.AddSingleton<LogsContext>(); return services; }
public interface IErrorLogService : IRepository<ErrorLog> { } public class ErrorLogService : MongoRepository<ErrorLog>, IErrorLogService { public ErrorLogService(LogsContext dbContext) : base(dbContext.ErrorLog) { } }
最后:
services.UserMongoLog(Configuration.GetSection("Mongo.Log"));
"Mongo.Log": { "DataBase": "PermissionSystem", "UserName": "sa", "Password": "shtx@123", "Services": [ { "Host": "192.168.1.6", "Port": "27017" } ] }
刚学洗使用MongoDB,才疏学浅,请大神多多指教