703 lines
25 KiB
C#
703 lines
25 KiB
C#
using Common;
|
|||
|
|
using MongoDB.Bson;
|
||
|
|
using MongoDB.Driver;
|
||
|
|
using MongoDB.Driver.Linq;
|
||
|
|
using MongoRepository.Attributes;
|
||
|
|
using MongoRepository.Config;
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Linq.Expressions;
|
||
|
|
using System.Text;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
|
||
|
|
using Microsoft.Extensions.Logging;
|
||
|
|
|
||
|
|
namespace MongoRepository
|
||
|
|
{
|
||
|
|
public class MongoBaseRepository<TDocument> : IMongoBaseRepository<TDocument> where TDocument : MongoBaseEntity
|
||
|
|
{
|
||
|
|
public readonly IMongoCollection<TDocument> _collection;
|
||
|
|
private readonly ILogger<MongoBaseRepository<TDocument>> _logger;
|
||
|
|
private static readonly HashSet<string> _indexedCollections = new();
|
||
|
|
|
||
|
|
public MongoBaseRepository(IMongoDbSettings settings, ILogger<MongoBaseRepository<TDocument>> logger)
|
||
|
|
{
|
||
|
|
_logger = logger;
|
||
|
|
var mongoUrl = new MongoUrlBuilder($"{settings.ServerUrl.TrimEnd('/')}")
|
||
|
|
{
|
||
|
|
Username = settings.Username,
|
||
|
|
Password = settings.Password,
|
||
|
|
DatabaseName = GetDataBaseName(typeof(TDocument))
|
||
|
|
}.ToMongoUrl();
|
||
|
|
|
||
|
|
var client = new MongoClient(mongoUrl);
|
||
|
|
|
||
|
|
EnsureDatabaseAndUser(client, settings, GetDataBaseName(typeof(TDocument)));
|
||
|
|
|
||
|
|
var database = client.GetDatabase(GetDataBaseName(typeof(TDocument)));
|
||
|
|
_collection = database.GetCollection<TDocument>(GetCollectionName(typeof(TDocument)));
|
||
|
|
|
||
|
|
EnsureIndexes(database);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void EnsureIndexes(IMongoDatabase database)
|
||
|
|
{
|
||
|
|
var collectionName = GetCollectionName(typeof(TDocument));
|
||
|
|
var key = $"{database.DatabaseNamespace.DatabaseName}:{collectionName}";
|
||
|
|
|
||
|
|
if (!_indexedCollections.Add(key))
|
||
|
|
return;
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (collectionName == "user")
|
||
|
|
{
|
||
|
|
var bsonCollection = database.GetCollection<BsonDocument>(collectionName);
|
||
|
|
var mobileIndex = new CreateIndexModel<BsonDocument>(
|
||
|
|
Builders<BsonDocument>.IndexKeys.Ascending("BaseInfo.Mobile"),
|
||
|
|
new CreateIndexOptions { Unique = true, Sparse = true, Name = "idx_baseinfo_mobile_unique" }
|
||
|
|
);
|
||
|
|
var idCardIndex = new CreateIndexModel<BsonDocument>(
|
||
|
|
Builders<BsonDocument>.IndexKeys.Ascending("RealName.IDCard"),
|
||
|
|
new CreateIndexOptions { Unique = true, Sparse = true, Name = "idx_realname_idcard_unique" }
|
||
|
|
);
|
||
|
|
bsonCollection.Indexes.CreateMany(new[] { mobileIndex, idCardIndex });
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
_logger.LogWarning(ex, "MongoDB 索引创建异常(可能已存在): collection={Collection}", collectionName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private void EnsureDatabaseAndUser(MongoClient client, IMongoDbSettings settings, string databaseName)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var databaseNames = client.ListDatabaseNames().ToList();
|
||
|
|
|
||
|
|
if (!databaseNames.Contains(databaseName))
|
||
|
|
{
|
||
|
|
var tempDatabase = client.GetDatabase(databaseName);
|
||
|
|
var tempCollection = tempDatabase.GetCollection<BsonDocument>("temp_collection");
|
||
|
|
|
||
|
|
var tempDoc = new BsonDocument("temp", "init");
|
||
|
|
tempCollection.InsertOne(tempDoc);
|
||
|
|
tempCollection.DeleteOne(new BsonDocument("temp", "init"));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex) when (ex.GetType().Name == "MongoAuthenticationException")
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
_logger.LogError(ex, "检查MongoDB数据库失败 database={DatabaseName}", databaseName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private protected string GetCollectionName(Type documentType)
|
||
|
|
{
|
||
|
|
var collectionName = ((BsonCollectionAttribute)documentType.GetCustomAttributes(
|
||
|
|
typeof(BsonCollectionAttribute),
|
||
|
|
true)
|
||
|
|
.FirstOrDefault())?.CollectionName;
|
||
|
|
var formatStr = Tools.RegexSubstring(collectionName, "{", "}");
|
||
|
|
if (!string.IsNullOrEmpty(collectionName) && !string.IsNullOrEmpty(formatStr))
|
||
|
|
{
|
||
|
|
collectionName = collectionName.Replace("{" + formatStr + "}", DateTime.Now.ToString(formatStr));
|
||
|
|
}
|
||
|
|
return collectionName;
|
||
|
|
}
|
||
|
|
|
||
|
|
private protected string GetDataBaseName(Type documentType)
|
||
|
|
{
|
||
|
|
return ((BsonCollectionAttribute)documentType.GetCustomAttributes(
|
||
|
|
typeof(BsonCollectionAttribute),
|
||
|
|
true)
|
||
|
|
.FirstOrDefault())?.DataBaseName;
|
||
|
|
}
|
||
|
|
public virtual IQueryable<TDocument> AsQueryable()
|
||
|
|
{
|
||
|
|
return _collection.AsQueryable();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual IMongoCollection<TDocument> GetCollection()
|
||
|
|
{
|
||
|
|
return _collection;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual IEnumerable<TDocument> FilterBy(
|
||
|
|
Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).ToEnumerable();
|
||
|
|
}
|
||
|
|
public virtual async Task<List<TDocument>> FilterByAsync(
|
||
|
|
Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return await _collection.Find(filterExpression).ToListAsync();
|
||
|
|
}
|
||
|
|
public virtual async Task<List<TDocument>> FilterByAsync(
|
||
|
|
FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return await _collection.Find(filterExpression).ToListAsync();
|
||
|
|
}
|
||
|
|
public virtual IEnumerable<TDocument> FilterBy(
|
||
|
|
FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).ToEnumerable();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual IEnumerable<TProjected> FilterBy<TProjected>(
|
||
|
|
Expression<Func<TDocument, bool>> filterExpression,
|
||
|
|
Expression<Func<TDocument, TProjected>> projectionExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).Project(projectionExpression).ToEnumerable();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual TDocument FindOne(FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).FirstOrDefault();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual Task<TDocument> FindOneAsync(FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return Task.Run(() => _collection.Find(filterExpression).FirstOrDefaultAsync());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual TDocument FindOne(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).FirstOrDefault();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual Task<TDocument> FindOneAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return Task.Run(() => _collection.Find(filterExpression).FirstOrDefaultAsync());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual TDocument FindOne(FilterDefinition<TDocument> filterExpression, Expression<Func<TDocument, object>> orderExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).SortByDescending(orderExpression).FirstOrDefault();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual Task<TDocument> FindOneAsync(FilterDefinition<TDocument> filterExpression, Expression<Func<TDocument, object>> orderExpression)
|
||
|
|
{
|
||
|
|
return Task.Run(() => _collection.Find(filterExpression).SortByDescending(orderExpression).FirstOrDefaultAsync());
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual TDocument FindOne(Expression<Func<TDocument, bool>> filterExpression, Expression<Func<TDocument, object>> orderExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).SortByDescending(orderExpression).FirstOrDefault();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual Task<TDocument> FindOneAsync(Expression<Func<TDocument, bool>> filterExpression, Expression<Func<TDocument, object>> orderExpression)
|
||
|
|
{
|
||
|
|
return Task.Run(() => _collection.Find(filterExpression).SortByDescending(orderExpression).FirstOrDefaultAsync());
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual TDocument FindById(string id)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
return _collection.Find(filter).SingleOrDefault();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual Task<TDocument> FindByIdAsync(string id)
|
||
|
|
{
|
||
|
|
return Task.Run(() =>
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
return _collection.Find(filter).SingleOrDefaultAsync();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
public virtual (long count, List<TDocument> list) QueryPage(Expression<Func<TDocument, bool>> filterExpression, Expression<Func<TDocument, object>> orderExpression, bool desc, int pageSize, int pageIndex)
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = _collection.Find(filterExpression).CountDocuments();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
var query = _collection.Find(filterExpression);
|
||
|
|
if (desc)
|
||
|
|
{
|
||
|
|
query = query.SortByDescending(orderExpression);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
query = query.SortBy(orderExpression);
|
||
|
|
}
|
||
|
|
var list = query.Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
|
||
|
|
return (count, list);
|
||
|
|
}
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageAsync(Expression<Func<TDocument, bool>> filterExpression, int pageSize, int pageIndex)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression);
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
|
||
|
|
return (count, list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageAsync(Expression<Func<TDocument, bool>> filterExpression,
|
||
|
|
Expression<Func<TDocument, object>> orderExpression, bool desc, int pageSize, int pageIndex)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression);
|
||
|
|
if (desc)
|
||
|
|
{
|
||
|
|
query = query.SortByDescending(orderExpression);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
query = query.SortBy(orderExpression);
|
||
|
|
}
|
||
|
|
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
|
||
|
|
return (count, list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageAsync(Expression<Func<TDocument, bool>> filterExpression,
|
||
|
|
Expression<Func<TDocument, object>> orderExpression, bool desc, int pageSize, int pageIndex, int skipCount)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression);
|
||
|
|
if (desc)
|
||
|
|
{
|
||
|
|
query = query.SortByDescending(orderExpression);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
query = query.SortBy(orderExpression);
|
||
|
|
}
|
||
|
|
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize + skipCount).Limit(pageSize).ToListAsync();
|
||
|
|
return (count - skipCount, list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageTwoOrderAsync(Expression<Func<TDocument, bool>> filterExpression,
|
||
|
|
Expression<Func<TDocument, object>> orderExpression, Expression<Func<TDocument, object>> thenorderExpression, bool desc, int pageSize, int pageIndex)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression);
|
||
|
|
if (desc)
|
||
|
|
{
|
||
|
|
query = query.SortByDescending(orderExpression).ThenByDescending(thenorderExpression);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
query = query.SortBy(orderExpression).ThenByDescending(thenorderExpression);
|
||
|
|
}
|
||
|
|
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize ).Limit(pageSize).ToListAsync();
|
||
|
|
return (count , list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageAsync(
|
||
|
|
FilterDefinition<TDocument> filterExpression, SortDefinition<TDocument> orderExpression, bool desc,
|
||
|
|
int pageSize, int pageIndex)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression).Sort(orderExpression);
|
||
|
|
|
||
|
|
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
|
||
|
|
return (count, list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual async Task<(long count, List<TDocument> list)> QueryPageAsync(
|
||
|
|
FilterDefinition<TDocument> filterExpression, SortDefinition<TDocument> orderExpression, bool desc,
|
||
|
|
int pageSize, int pageIndex, int skipIndex)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
pageSize = pageSize <= 0 ? 10 : pageSize;
|
||
|
|
pageIndex = pageIndex <= 0 ? 1 : pageIndex;
|
||
|
|
var count = await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
if (count == 0)
|
||
|
|
{
|
||
|
|
return (0, new List<TDocument>());
|
||
|
|
}
|
||
|
|
|
||
|
|
var query = _collection.Find(filterExpression).Sort(orderExpression);
|
||
|
|
|
||
|
|
|
||
|
|
var list = await query.Skip((pageIndex - 1) * pageSize + skipIndex).Limit(pageSize).ToListAsync();
|
||
|
|
return (count - skipIndex, list);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
throw ex;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
public virtual (bool ok, string message) InsertOne(TDocument document)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.InsertOne(document);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual async Task<(bool ok, string message)> InsertOneAsync(TDocument document)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await Task.Run(() => _collection.InsertOneAsync(document));
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public (bool ok, string message) InsertMany(ICollection<TDocument> documents)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.InsertMany(documents);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public virtual async Task<(bool ok, string message)> InsertManyAsync(ICollection<TDocument> documents)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await Task.Run(() => _collection.InsertManyAsync(documents));
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public (bool ok, string message) ReplaceOne(TDocument document)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
|
||
|
|
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.FindOneAndReplace(filter, document);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual (bool ok, string message) UpdateById(string id, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
var result = _collection.UpdateOne(filter, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
public virtual async Task<(bool ok, string message)> UpdateByIdAsync(string id, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var result = await _collection.UpdateOneAsync(filter, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public virtual async Task<long> CountAsync(
|
||
|
|
Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual long Count(
|
||
|
|
Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).CountDocuments();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
public virtual async Task<long> CountAsync(
|
||
|
|
FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return await _collection.Find(filterExpression).CountDocumentsAsync();
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual long Count(
|
||
|
|
FilterDefinition<TDocument> filterExpression)
|
||
|
|
{
|
||
|
|
return _collection.Find(filterExpression).CountDocuments();
|
||
|
|
}
|
||
|
|
public virtual (bool ok, string message) UpdateMany(Expression<Func<TDocument, bool>> filterExpression, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
var result = _collection.UpdateMany(filterExpression, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
public virtual async Task<(bool ok, string message)> UpdateManyAsync(Expression<Func<TDocument, bool>> filterExpression, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var result = await _collection.UpdateManyAsync(filterExpression, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual (bool ok, string message) UpdateMany(FilterDefinition<TDocument> filterExpression, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
var result = _collection.UpdateMany(filterExpression, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
public virtual async Task<(bool ok, string message)> UpdateManyAsync(FilterDefinition<TDocument> filterExpression, UpdateDefinition<TDocument> updateDefinition)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var result = await _collection.UpdateManyAsync(filterExpression, updateDefinition);
|
||
|
|
return (result.IsAcknowledged, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public virtual async Task<(bool ok, string message)> ReplaceOneAsync(TDocument document)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, document.Id);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await _collection.FindOneAndReplaceAsync(filter, document);
|
||
|
|
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public (bool ok, string message) DeleteOne(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.FindOneAndDelete(filterExpression);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<(bool ok, string message)> DeleteOneAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await Task.Run(() => _collection.FindOneAndDeleteAsync(filterExpression));
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public (bool ok, string message) DeleteById(string id)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.FindOneAndDelete(filter);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<(bool ok, string message)> DeleteByIdAsync(string id)
|
||
|
|
{
|
||
|
|
var filter = Builders<TDocument>.Filter.Eq(doc => doc.Id, id);
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var deleted = await _collection.FindOneAndDeleteAsync(filter);
|
||
|
|
if (deleted == null)
|
||
|
|
return (false, "记录不存在或已删除");
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public (bool ok, string message) DeleteMany(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
_collection.DeleteMany(filterExpression);
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<(bool ok, string message)> DeleteManyAsync(Expression<Func<TDocument, bool>> filterExpression)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
await _collection.DeleteManyAsync(filterExpression);
|
||
|
|
|
||
|
|
return (true, null);
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
|
||
|
|
return (false, ex.Message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public async Task<List<BsonDocument>> Aggregate(FilterDefinition<TDocument> filterExpression, ProjectionDefinition<TDocument, BsonDocument> group)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var res = await Task.Run(() => _collection.Aggregate().Match(filterExpression).Group(group).ToList());
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<List<TDocument>> RandomData(Expression<Func<TDocument, bool>> filterExpression, int count)
|
||
|
|
{
|
||
|
|
try
|
||
|
|
{
|
||
|
|
var res = await Task.Run(() =>
|
||
|
|
_collection.AsQueryable().Where(filterExpression).Sample(count).ToList());
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|