2024-11-13 17:50:52 +08:00

353 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using JiShe.CollectBus.Common.Interfaces;
using JiShe.CollectBus.EntityFrameworkCore;
using Volo.Abp.Timing;
namespace JiShe.CollectBus.MongoDB
{
public class MongoBaseRepository<T> : IMongoRepository<T> where T : class, new()
{
private readonly IMongoContext _context;
private readonly IMongoCollection<T> _dbSet;
private readonly IClock _clock;
public MongoBaseRepository(IMongoContext context, IClock clock)
{
_context = context;
_clock = clock;
var collectionName = typeof(T).GetCustomAttribute<TableAttribute>()?.Name ?? typeof(T).Name;
_dbSet = _context.GetCollection<T>(collectionName);
}
#region
/// <summary>
/// 事务添加数据
/// </summary>
/// <param name="session">MongoDB 会话session对象</param>
/// <param name="objData">添加数据</param>
/// <returns></returns>
public async Task AddTransactionsAsync(IClientSessionHandle session, T objData)
{
await _context.AddCommandAsync(async (session) => await _dbSet.InsertOneAsync(objData));
}
/// <summary>
/// 事务数据删除
/// </summary>
/// <param name="session">MongoDB 会话session对象</param>
/// <param name="id">objectId</param>
/// <returns></returns>
public async Task DeleteTransactionsAsync(IClientSessionHandle session, string id)
{
await _context.AddCommandAsync((session) => _dbSet.DeleteOneAsync(Builders<T>.Filter.Eq(" _id ", id)));
}
/// <summary>
/// 事务异步局部更新(仅更新一条记录)
/// </summary>
/// <param name="session">MongoDB 会话session对象</param>
/// <param name="filter">过滤器</param>
/// <param name="update">更新条件</param>
/// <returns></returns>
public async Task UpdateTransactionsAsync(IClientSessionHandle session, FilterDefinition<T> filter, UpdateDefinition<T> update)
{
await _context.AddCommandAsync((session) => _dbSet.UpdateOneAsync(filter, update));
}
#endregion
#region
/// <summary>
/// 添加数据
/// </summary>
/// <param name="objData">添加数据</param>
/// <returns></returns>
public async Task AddAsync(T objData)
{
if (typeof(IReceived).IsAssignableFrom(typeof(T)))
{
(objData as IReceived)!.ReceivedTime = $"{_clock.Now:yyyy-MM-dd HH:mm:ss}";
}
await _dbSet.InsertOneAsync(objData);
}
/// <summary>
/// 批量插入
/// </summary>
/// <param name="objDatas">实体集合</param>
/// <returns></returns>
public async Task InsertManyAsync(List<T> objDatas)
{
await _dbSet.InsertManyAsync(objDatas);
}
#endregion
#region
/// <summary>
/// 数据删除
/// </summary>
/// <param name="id">objectId</param>
/// <returns></returns>
public async Task DeleteAsync(string id)
{
await _dbSet.DeleteOneAsync(Builders<T>.Filter.Eq("_id", new ObjectId(id)));
}
/// <summary>
/// 异步删除多条数据
/// </summary>
/// <param name="filter">删除的条件</param>
/// <returns></returns>
public async Task<DeleteResult> DeleteManyAsync(FilterDefinition<T> filter)
{
return await _dbSet.DeleteManyAsync(filter);
}
#endregion
#region
/// <summary>
/// 指定对象异步修改一条数据
/// </summary>
/// <param name="obj">要修改的对象</param>
/// <param name="id">修改条件</param>
/// <returns></returns>
public async Task UpdateAsync(T obj, string id)
{
//修改条件
FilterDefinition<T> filter = Builders<T>.Filter.Eq("_id", new ObjectId(id));
//要修改的字段
var list = new List<UpdateDefinition<T>>();
foreach (var item in obj.GetType().GetProperties())
{
if (item.Name.ToLower() == "id") continue;
list.Add(Builders<T>.Update.Set(item.Name, item.GetValue(obj)));
}
var updatefilter = Builders<T>.Update.Combine(list);
await _dbSet.UpdateOneAsync(filter, updatefilter);
}
/// <summary>
/// 局部更新(仅更新一条记录)
/// <para><![CDATA[expression 参数示例x => x.Id == 1 && x.Age > 18 && x.Gender == 0]]></para>
/// <para><![CDATA[entity 参数示例y => new T{ RealName = "Ray", Gender = 1}]]></para>
/// </summary>
/// <param name="expression">筛选条件</param>
/// <param name="entity">更新条件</param>
/// <returns></returns>
public async Task UpdateAsync(Expression<Func<T, bool>> expression, Expression<Action<T>> entity)
{
var fieldList = new List<UpdateDefinition<T>>();
if (entity.Body is MemberInitExpression param)
{
foreach (var item in param.Bindings)
{
var propertyName = item.Member.Name;
object propertyValue = null;
if (item is not MemberAssignment memberAssignment) continue;
if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
{
if (memberAssignment.Expression is ConstantExpression constantExpression)
propertyValue = constantExpression.Value;
}
else
{
propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
}
if (propertyName != "_id") //实体键_id不允许更新
{
fieldList.Add(Builders<T>.Update.Set(propertyName, propertyValue));
}
}
}
await _dbSet.UpdateOneAsync(expression, Builders<T>.Update.Combine(fieldList));
}
/// <summary>
/// 异步局部更新(仅更新一条记录)
/// </summary>
/// <param name="filter">过滤器</param>
/// <param name="update">更新条件</param>
/// <returns></returns>
public async Task UpdateAsync(FilterDefinition<T> filter, UpdateDefinition<T> update)
{
await _dbSet.UpdateOneAsync(filter, update);
}
/// <summary>
/// 异步局部更新(仅更新多条记录)
/// </summary>
/// <param name="expression">筛选条件</param>
/// <param name="update">更新条件</param>
/// <returns></returns>
public async Task UpdateManyAsync(Expression<Func<T, bool>> expression, UpdateDefinition<T> update)
{
await _dbSet.UpdateManyAsync(expression, update);
}
/// <summary>
/// 异步批量修改数据
/// </summary>
/// <param name="dic">要修改的字段</param>
/// <param name="filter">更新条件</param>
/// <returns></returns>
public async Task<UpdateResult> UpdateManayAsync(Dictionary<string, string> dic, FilterDefinition<T> filter)
{
T t = new T();
//要修改的字段
var list = new List<UpdateDefinition<T>>();
foreach (var item in t.GetType().GetProperties())
{
if (!dic.ContainsKey(item.Name)) continue;
var value = dic[item.Name];
list.Add(Builders<T>.Update.Set(item.Name, value));
}
var updatefilter = Builders<T>.Update.Combine(list);
return await _dbSet.UpdateManyAsync(filter, updatefilter);
}
#endregion
#region
/// <summary>
/// 通过ID主键获取数据
/// </summary>
/// <param name="id">objectId</param>
/// <returns></returns>
public async Task<T> GetByIdAsync(string id)
{
var queryData = await _dbSet.FindAsync(Builders<T>.Filter.Eq("_id", new ObjectId(id)));
return queryData.FirstOrDefault();
}
/// <summary>
/// 获取所有数据
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<T>> GetAllAsync()
{
var queryAllData = await _dbSet.FindAsync(Builders<T>.Filter.Empty);
return queryAllData.ToList();
}
/// <summary>
/// 获取记录数
/// </summary>
/// <param name="expression">筛选条件</param>
/// <returns></returns>
public async Task<long> CountAsync(Expression<Func<T, bool>> expression)
{
return await _dbSet.CountDocumentsAsync(expression);
}
/// <summary>
/// 获取记录数
/// </summary>
/// <param name="filter">过滤器</param>
/// <returns></returns>
public async Task<long> CountAsync(FilterDefinition<T> filter)
{
return await _dbSet.CountDocumentsAsync(filter);
}
/// <summary>
/// 判断是否存在
/// </summary>
/// <param name="predicate">条件</param>
/// <returns></returns>
public async Task<bool> ExistsAsync(Expression<Func<T, bool>> predicate)
{
return await Task.FromResult(_dbSet.AsQueryable().Any(predicate));
}
/// <summary>
/// 异步查询集合
/// </summary>
/// <param name="filter">查询条件</param>
/// <param name="field">要查询的字段,不写时查询全部</param>
/// <param name="sort">要排序的字段</param>
/// <returns></returns>
public async Task<List<T>> FindListAsync(FilterDefinition<T> filter, string[]? field = null, SortDefinition<T>? sort = null)
{
//不指定查询字段
if (field == null || field.Length == 0)
{
if (sort == null) return await _dbSet.Find(filter).ToListAsync();
return await _dbSet.Find(filter).Sort(sort).ToListAsync();
}
//指定查询字段
var fieldList = new List<ProjectionDefinition<T>>();
for (int i = 0; i < field.Length; i++)
{
fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
}
var projection = Builders<T>.Projection.Combine(fieldList);
fieldList?.Clear();
//不排序
if (sort == null) return await _dbSet.Find(filter).Project<T>(projection).ToListAsync();
//排序查询
return await _dbSet.Find(filter).Sort(sort).Project<T>(projection).ToListAsync();
}
/// <summary>
/// 异步分页查询集合
/// </summary>
/// <param name="filter">查询条件</param>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">页容量</param>
/// <param name="field">要查询的字段,不写时查询全部</param>
/// <param name="sort">要排序的字段</param>
/// <returns></returns>
public async Task<List<T>> FindListByPageAsync(FilterDefinition<T> filter, int pageIndex, int pageSize, string[]? field = null, SortDefinition<T>? sort = null)
{
//不指定查询字段
if (field == null || field.Length == 0)
{
if (sort == null) return await _dbSet.Find(filter).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
//进行排序
return await _dbSet.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
}
//指定查询字段
var fieldList = new List<ProjectionDefinition<T>>();
for (int i = 0; i < field.Length; i++)
{
fieldList.Add(Builders<T>.Projection.Include(field[i].ToString()));
}
var projection = Builders<T>.Projection.Combine(fieldList);
fieldList?.Clear();
//不排序
if (sort == null) return await _dbSet.Find(filter).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
//排序查询
return await _dbSet.Find(filter).Sort(sort).Project<T>(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
}
#endregion
}
}