Создание класса для подключения к mongo на C#

#c# #mongodb #api

Вопрос:

Я создаю класс для подключения и запроса базы данных mongo для веб-api REST в веб-приложении .Net Framework 4.8. API будет работать в Windows Server с использованием IIS.

Поэтому у меня было несколько сомнений в том, что будет лучше при подключении и запросе на монго.Исходя из этого, я придумал 3 различных способа создания этого класса.

Мое первое сомнение заключается в том, следует ли мне сохранять соединение в закрытой переменной и создавать функции, которые использовали только это единственное соединение, или следует создавать соединение для каждого запроса?

Мое второе сомнение заключается в том, что если я решу сохранить соединение в частной переменной, то лучше ли для класса быть классом экземпляра или статическим классом?

Каковы » за » и «против» каждого из способов?

Есть ли какие-либо проблемы, которые могут возникнуть в любом из них?

Делаю ли я плохую практику программирования каким-либо из этих способов?

 //Static class with private connection variable
public static class MongoTables
{
    private static IMongoCollection<object> collec;
    private static MongoClient client;
    public static void Connect(string connectionString)
    {
        client = new MongoClient(connectionString);
        collec = client.GetDatabase("MyDatabase").GetCollection<object>("MyCollection");
    }
    public static object GetFirst(string value)
    {
        return collec.AsQueryable<object>().First(t => t.Field1 == value);
    }
    public static List<object> GetList(string value)
    {
        return collec.AsQueryable<object>().Where(t => t.Field1 == value).ToList();
    }
}
//Static class with a connection for each query
public static class MongoTables
{
    
    public static object GetFirst(string value)
    {
        using(MongoClient client = new MongoClient("connectionString"))
            return client.GetDatabase("MyDatabase").GetCollection<object>("MyCollection").AsQueryable<object>().First(t => t.Field1 == value);
    }
    public static List<object> GetList(string value)
    {
        using(MongoClient client = new MongoClient("connectionString"))
            return client.GetDatabase("MyDatabase").GetCollection<object>("MyCollection").AsQueryable<object>().Where(t => t.Field1 == value).ToList();
    }
}
//Instance class with private connection variable
public class MongoTables
{
    private IMongoCollection<object> collec;
    private MongoClient client;
    
    public MongoTables(string connectionString)
    {
        client = new MongoClient(connectionString);
        collec = client.GetDatabase("MyDatabase").GetCollection<object>("MyCollection");
    }
    public object GetFirst(string value)
    {
        return collec.AsQueryable<object>().First(t => t.Field1 == value);
    }
    public List<object> GetList(string value)
    {
        return collec.AsQueryable<object>().Where(t => t.Field1 == value).ToList();
    }
}
 

Ответ №1:

Класс контекста, в вашем случае, MongoTables должен иметь область действия или временное время жизни. Также вам нужно использовать DI для IMongoClient с Singleton пожизненным сроком службы и удалить Connect из контекстного класса. В Startup классе зарегистрируйте свою зависимость, как services.AddSingleton<IMongoClint>(_ => new MongoClient("some connection string")) и все)

Кроме того, я рекомендую вам использовать фильтры вместо IQueryable