Как передать строку подключения из appsettings. [Name] .json в DbContext в .NET Core? - PullRequest
0 голосов
/ 04 мая 2018

У меня есть приложение .net core. Я записываю строку подключения в файл appsettings.json. Но теперь я хочу получить эту строку подключения для моего контекста. Как это сделать?

В .net Framework 4.6 я использовал это:

ConfigurationManager.ConnectionStrings["ConnStrName"].ConnectionString;

У меня есть appsettings.Development.json, как это (*** может быть любым именем):

"ConnectionStrings": {
    "***": "Server=***;Database=****;Trusted_Connection=True;MultipleActiveResultSets=true;"
  }

Я добавил услугу:

services.AddTransient<MyContext>(provider =>
            {
                return new MyContext(configuration["ConnectionStrings:***"]);
            });

и это конструктор контекста (ТОЛЬКО ЭТО, а не конструктор по умолчанию, потому что если я пишу по умолчанию, он не берет мою строку подключения из файла json):

public MyContext(string connectionString)
        : base(connectionString)
    {
        try
        {
            this.Database.Log = (s) => System.Diagnostics.Debug.Write(s);
        }
        catch (Exception e)
        {
            //CurrentLogger.Log.Error(e);
        }
    }

После этого у меня появляется эта ошибка после запуска команды Enable-Migration

Целевой контекст «MyContext» не может быть создан. Добавьте конструктор по умолчанию или предоставьте реализацию IDbContextFactory.

Если бы я как-то мог получить строку подключения от json здесь:

enter image description here

все будет хорошо. Но я хочу сделать это с одной строкой в ​​ .NET CORE , если это возможно, как в .net framework: с этим:

ConfigurationManager.ConnectionStrings["ConnStrName"].ConnectionString;

.net framework 4.6

enter image description here

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Мой оригинальный ответ не сработает для вашей ситуации, потому что я предполагал, что вы переходите на .NET Core, вместо того чтобы поддерживать совместимость между полноценными проектами .NET Framework и новым проектом .NET Core.

Я сделал нечто похожее с устаревшими проектами и в итоге создал класс, который действовал как хранилище для строк подключения, а затем он заполнялся бы по-разному, в зависимости от того, какой проект его использует .NET Core или полный .NET Framework .

Для полных проектов .NET Framework он заполняет строки подключения из ConfigurationManager.

Для проектов .NET Core вы должны прочитать строки подключения из вашего appsettings.json, а затем передать строки подключения этому классу при запуске.

Тогда вам придется изменить ссылки на ConfigurationManager в вашем DbContext на новый класс, который вы создали для получения строк подключения.

public class DatabaseConfiguration
{
    /// <summary>
    /// Database Connection Strings
    /// </summary>
    private static List<ConnectionStringSettings> _conStrings;
    public static List<ConnectionStringSettings> ConnectionStrings
    {
        get
        {
            //If it wasn't initialized manually, Initialize using the Configuration Manager. 
            if (_conStrings == null || !_conStrings.Any())
            {
                Initialize();
            }

            return _conStrings;
        }
    }

    /// <summary>
    /// Sets the connection strings from the Configuration Manager.
    /// </summary>
    public static void Initialize()
    {
        _conStrings = new List<ConnectionStringSettings>();
            foreach (ConnectionStringSettings connection in ConfigurationManager.ConnectionStrings)
            {
                _conStrings.Add(connection);
            }
    }

    /// <summary>
    /// Sets the connection strings manually. This is used when the project is a .NET Core app because it doesn't use the Configuration Manager, app.config, or web.config.
    /// </summary>
    public static void Initialize(List<ConnectionStringSettings>connectionStrings)
    {                
        _conStrings = connectionSttrings;
    }

/// <summary>
/// Gets the connection string for a database with the given name.
/// </summary>
/// <param name="name">DB Name</param>
/// <returns>Connection String</returns>
public static string GetConnectionString(string name)
{
    var matchingConnection = ConnectionStrings.Find(c => c.Name == name);
    return matchingConnection?.ConnectionString;
}

}
0 голосов
/ 04 мая 2018

Все в .NET Core построено на внедрении зависимостей, а не на статических экземплярах таких вещей, как ConfigurationManager.

Вы можете сделать это несколькими разными способами.

Сначала нужно зарегистрировать ваш DbContext в Startup.cs ConfigureServices, используя что-то вроде этого:

services.AddDbContext<MyContext>(context => context.UseSqlServer(Configuration.GetConnectionString("name")));

Затем, когда ваш репозиторий / служба / любой другой класс должен использовать Контекст, он будет внедрен в класс с помощью конструктора, чтобы вы могли его использовать.

public class SomeClass(MyContext context)
{

}

Или, если вы не хотите делать это таким образом, вы можете также вставить 'IConfiguration' в конструктор вашего DbContext и затем использовать IConfiguration, чтобы получить строку подключения:

public class SomeClass(IConfiguration config)
{
    config.GetConnectionString("name")
}
...