【问题标题】:How can I implement DbContext Connection String in .NET Core?如何在 .NET Core 中实现 DbContext 连接字符串?
【发布时间】:2016-12-17 02:48:42
【问题描述】:

我的情况与此链接非常相​​似,或者至少我的代码相似,我正在尝试找到一种在 .NET Core 语法中应用相同方法的方法。

Pass connection string to code-first DbContext

我的具体代码如下:

public partial class CompanyFormsContext : DbContext
{
    public CompanyFormsContext()
        : base("name=CompanyFormsContext")
    {
    }

    public CompanyFormsContext(string connName)
        : base("name=" + connName)
    {
    }
    ...
}

我收到一条错误消息:

错误 CS1503 参数 1:无法从“字符串”转换为“Microsoft.EntityFrameworkCore.DbContextOptions”CompanyForms..NETCoreApp,Version=v1.0

当我遍历base("name=CompanyFormsContext")base("name=" = connName) 中的括号时。

在 .NET Core 中实现此功能的正确方法是什么?

编辑:

我想分享一下,我的 appsettings.json 文件中有以下数据库连接信息:(但是,我在 startup.cs 中没有设置)

  "Data": {
    "CompanyFormsContext": {
      "ConnectionString": "Server=(localdb)\\projectsv13;Database=companyforms;Trusted_Connection=True;"
    },
    "CompanyFormsContextQA": {
      "ConnectionString": "Server=(localdb)\\projectsv13;Database=companyforms;Trusted_Connection=True;"
    }
  }

我在网站上找到了以下链接Adding DbContextOptions in Startup.cs not registering data store,我想知道一个简单的protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 是否足以修复我的连接?

来自链接:

services.AddEntityFramework(Configuration)
    .AddSqlServer()
    .AddDbContext<MyDbContext>(
        options =>
        options.UseSqlServer(Configuration.Get("Data:CompanyFormsContext:ConnectionString"))
    );

我的 Startup.cs 中是否需要这种服务?

【问题讨论】:

  • 该链接对于学习不同类型的 Db 连接非常有用,我现在更加清楚问题所在。谢谢。
  • 抱歉错过了您的编辑。肯定在正确的轨道上,看看我的回答是否有帮助。

标签: c# asp.net .net entity-framework


【解决方案1】:

另一种选择是调用采用 DbContextOptions 的基本构造函数:

public BooksContext(string connectionString) : base(GetOptions(connectionString))
{
}

private static DbContextOptions GetOptions(string connectionString)
{
    return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
}

【讨论】:

  • 不得不将 this 更改为 base 但很好的解决方案!
  • 我如何将它用于 oracle 数据库?,没有 UseOracle 或类似的东西..
  • 微软没有为Oracle提供一个,你需要使用第三方。根据它,扩展方法可能会有所不同。请参阅docs.microsoft.com/en-us/ef/core/providers
  • 如果需要得到强类型的DbContextOptions&lt;TContext&gt;,则需要使用new DbContextOptionsBuilder&lt;BooksContext&gt;
  • 它的工作。这个答案对我帮助很大。谢谢。
【解决方案2】:

通常您会希望在启动时从配置中读取它,然后使用连接字符串为您的进程配置实体框架 DbContext 服务。

1) 在您的 appsettings.json 中添加一行:

"DbConnectionString": "Server=s;Database=db;Trusted_Connection=True;",

2) 像这样读取 Startup.cs 类中的行(在调用 Startup 方法来构建配置之后 - 通常在 ConfigureServices 方法中):

var connection = Configuration["DbConnectionString"];

3) 如果使用实体框架添加一个数据库上下文服务(MyDbContext 是 EF 生成的上下文类)。您还想告诉内置依赖注入如何实例化您的数据库上下文:

services.AddDbContext<MyDbContext>(options => options.UseSqlServer(connection));
services.AddScoped<IMyDbContext, MyDbContext>();

IMyDbContext 是哪里(简单地说)只是你从 MyDbContext 中提取的一个接口

4) 现在你可以定义你的控制器来获取一个 MyDbContext 并且 DI 将负责构建它并在调用控制器时将其传递:

public MyController(IMyDbContext context)
{
    _context = context  // store for later use
}

【讨论】:

    【解决方案3】:

    IMO 最佳实践:

    添加到您的 configuration.json

         "ConnectionStrings": {
        "BooksContext": "Server=MyServer;Database=MyDb;Trusted_Connection=True;"
      }
    

    初始化部分:

    services.AddDbContext<BooksContext>(options => options.UseSqlServer(configuration.GetConnectionString(nameof(BooksContext))));
    

    【讨论】:

      【解决方案4】:

      用于静态连接的 Startup.cs

      services.AddScoped<MyContext>(_ => new MyContext(Configuration.GetConnectionString("myDB")));
      

      动态连接的Table1Repository.cs

      using (var _context = new MyContext(@"server=....){
      context.Table1....
      }
      

      MyContext.cs

      public MyContext(string connectionString) : base(GetOptions(connectionString))
      {
      }
      
      private static DbContextOptions GetOptions(string connectionString)
      {
          return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
      }
      

      【讨论】:

        【解决方案5】:

        因此,我到处寻找解决问题的方法,即我需要根据直到进行连接时才拥有的数据动态连接到数据库。基本上,动态上下文。我没有通过 URL 传递数据,也没有可以附加到的可能数据库的简短列表)。所以,这是我对所提出问题的解决方案。此代码将允许您使用 appsettings.json 文件定义连接字符串,其中包含在运行时由代码替换的占位符。这可以在控制器或其他您认为合适的类中完成。

        我同时使用静态上下文和动态上下文,但您只能使用动态上下文。

        希望有人偶然发现这一点并说感谢上帝……尽管可能有人会说,这家伙疯了。不管怎样,尽情享受吧。

        using System;
        using System.Globalization;
        using System.Linq;
        using Microsoft.Extensions.Configuration;
        
        namespace CallCenter.Repositories
        {
            public class TestRepository : ITestRepository 
            {
                private readonly InsuranceContext _context;
                public TestRepository(InsuranceContext context)
                {
                    _context = context;
                }
        
                public void Add(string passedInStringWhichTellsWhatDatabaseToUse)
                {
                    var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
        
                    var configuration = builder.Build();
                    var connectionString = configuration.GetConnectionString("DefaultConnection");
                    
        
                        var agencyContext = new AgencyContext(connectionString.Replace("Database=replacethisstring", "Database=" + passedInStringWhichTellsWhatDatabaseToUse));
        
                        var company = agencyContext.Companys.FirstOrDefault(x => x.ColumnNameInDb == "xyz");
                        if (company != null)
                        {
                            companyId = company.CompanyId.ToString();
                        }
        
        ... your other code here which could include the using the passed in _context from the injected code (or you could not have any context passed in and just use dynamic context
                    }
        
                }
            }
        }
        
        //The AgencyContext class would look like this:
        
        using Microsoft.EntityFrameworkCore;
        
        namespace CallCenter.Entities
        {
            public class AgencyContext : DbContext
            {
                public AgencyContext(string connectionString) : base(GetOptions(connectionString))
                {
                    
                }
        
                private static DbContextOptions GetOptions(string connectionString)
                {
                    return SqlServerDbContextOptionsExtensions.UseSqlServer(new DbContextOptionsBuilder(), connectionString).Options;
                }
        
                public DbSet<Companys> Companys { get; set; }
            }
        }
        
        //The startup.c IServiceProvider module has this:
        
                public IServiceProvider ConfigureServices(IServiceCollection services)
                {
                    services.AddOptions();
                   
                    services.AddDbContext<InsuranceContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), b => b.UseRowNumberForPaging()));
                    services.AddScoped<ITestRepository , TestRepository >();
        ....
        }
        

        最后 appsettings.jason 文件中会包含以下内容:

        {
          "ConnectionStrings": {
            "DefaultConnection": "Server=yourservername;Database=replacethisstring;User ID=youruserid;Password=yourpassword;TrustServerCertificate=True;Trusted_Connection=False;Connection Timeout=30;Integrated Security=False;Persist Security Info=False;Encrypt=True;MultipleActiveResultSets=True;",
        }
        }
        

        【讨论】:

          【解决方案6】:

          一种简单的方法是,只需使用选项构建器来获取上下文:

              public static MyDbContext GetMyDbContext(string databaseName)
              {
                  var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>();
          
                  optionsBuilder.UseSqlServer($@"Data Source=.\SqlExpress;Initial Catalog={databaseName};Integrated Security=True");
          
                  return new MyDbContext(optionsBuilder.Options);
          
              }
          

          【讨论】:

            猜你喜欢
            • 2021-11-18
            • 2021-11-16
            • 2019-04-21
            • 1970-01-01
            • 1970-01-01
            • 2020-12-07
            • 2019-01-07
            相关资源
            最近更新 更多