网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Linq.Expressions;
using System.Security;
using System.Threading;
using Dpz.Core.Infrastructure;
using Dpz.Core.Infrastructure.Entity;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
using MongoDB.Driver.Linq;

namespace Dpz.Core.MongodbAccess;

public abstract class MongodbAccess
{
    private readonly record struct Db(string DatabaseName, IMongoClient Client);

    private static readonly Lazy<ConcurrentDictionary<string, Db>> LazyMongoClients = new();

    private readonly string _connectionString;

    internal MongodbAccess(string? connectionString)
    {
        if (string.IsNullOrEmpty(connectionString))
        {
            if (!LazyMongoClients.Value.IsEmpty)
            {
                _connectionString = LazyMongoClients.Value.First().Key;
                return;
            }

            throw new Exception("mongodb connection string is not configured");
        }

        _connectionString = connectionString;
        TryAddClient(connectionString);
    }

    /// <summary>
    /// 获取Mongodb客户端
    /// </summary>
    internal IMongoClient Client => LazyMongoClients.Value[_connectionString].Client ??
                                    throw new Exception("IMongoClient value is null");

    /// <summary>
    /// 获取 MongoDB 数据库
    /// </summary>
    internal IMongoDatabase Database => Client.GetDatabase(LazyMongoClients.Value[_connectionString].DatabaseName);

    protected ILoggerFactory LoggerFactoryDb => LoggerFactory.Create(loggerBuilder =>
        loggerBuilder
            .AddConsole()
            .AddDebug());

    internal static IClientSessionHandle StartSession(string? connectionString,
        CancellationToken cancellationToken = default)
    {
        if (string.IsNullOrEmpty(connectionString))
            throw new Exception("connection string has no value");

        TryAddClient(connectionString);

        return LazyMongoClients.Value[connectionString].Client.StartSession(cancellationToken: cancellationToken);
    }

    private static void TryAddClient(string connectionString)
    {
        if (LazyMongoClients is not { IsValueCreated: true } || !LazyMongoClients.Value.ContainsKey(connectionString))
        {
            var url = MongoUrl.Create(connectionString);
            var databaseName = string.IsNullOrEmpty(url.DatabaseName)
                ? throw new Exception("no database specified")
                : url.DatabaseName;
            LazyMongoClients.Value.TryAdd(connectionString, new Db(databaseName, new MongoClient(url)));
        }
    }
}

/// <summary>
/// Mongodb 数据库访问抽象类
/// </summary>
/// <typeparam name="T"></typeparam>
public sealed class MongodbAccess<T> : MongodbAccess where T : IBaseEntity, new()
{
    public MongodbAccess(string? connectionString) : base(connectionString)
    {
    }

    public MongodbAccess(string? connectionString, string collectionName) : base(connectionString)
    {
        CollectionName = collectionName;
    }

    /// <summary>
    /// database collection name
    /// </summary>
    internal readonly string CollectionName = typeof(T).Name;

    /// <summary>
    /// 获取 该实体中 MongoDB数据库的集合
    /// </summary>
    public IMongoCollection<T> Collection => Database.GetCollection<T>(CollectionName);

    /// <summary>
    /// 获取 提供对MongoDB数据查询的Queryable
    /// </summary>
    /// <returns></returns>
    public IMongoQueryable<T> MongoQueryable => Database.GetCollection<T>(CollectionName).AsQueryable(
        //update 2020年5月6日 内存限制写入临时文件 https://docs.mongodb.com/manual/reference/command/aggregate/
        new AggregateOptions { AllowDiskUse = true });
}
loading