加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core-mvc – 创建多个dbcontexts的MVC 6 EF7 RC1

发布时间:2020-12-16 07:20:29 所属栏目:asp.Net 来源:网络整理
导读:我试图弄清楚如何在EF7 RC1中创建第二个DB上下文.在过去,我可以使用带有:base(“connectionName”)的构造函数,但这似乎不再是一个选项,因为它说不能将字符串转换为System.IServiceProvider. 我的第二个上下文代码如下: public class DecAppContext : DbCon
我试图弄清楚如何在EF7 RC1中创建第二个DB上下文.在过去,我可以使用带有:base(“connectionName”)的构造函数,但这似乎不再是一个选项,因为它说不能将字符串转换为System.IServiceProvider.

我的第二个上下文代码如下:

public class DecAppContext : DbContext
    {

        public DecAppContext()
          //  :base("DefaultConnection")
        {

        }
        public DbSet<VignetteModels> VignetteModels { get; set; }
        public DbSet<VignetteResult> Result { get; set; }
    }
}

在我的config.json中,我指定了连接:

"Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=(localdb)mssqllocaldb;Database=aspnet5-xxxxx...;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  }

在我的启动的配置服务部分中,我添加了两个上下文:

services.AddEntityFramework()
                .AddSqlServer()
                .AddDbContext<ApplicationDbContext>(options =>
                    options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]))
                .AddDbContext<DecAppContext>(options => options.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

applicationDB上下文工作正常,因为我可以创建用户并登录而不会出现问题

但是,当我尝试通过以下方式访问控制器中的其他上下文时:

private DecAppContext db = new DecAppContext();
var vignette = db.VignetteModels.SingleOrDefault(v => v.CaseId == vid);

我收到错误:

No database providers are configured. Configure a database provider by
overriding OnConfiguring in your DbContext class or in the
AddDbContext method when setting up services.

EF7 RC1中具有多个数据库上下文并访问它们的任何工作示例都将非常受欢迎.

解决方法

首先,我会从GitHub上的EntityFramework的wiki推荐你 the article.本文介绍了许多定义DbContext的方法,它引用了appsettings.json的一部分.我个人更喜欢使用[FromServices]属性的方式.

代码可以是以下内容:

首先,您使用以下内容定义了appsettings.json

{
  "Data": {
    "ApplicationDbConnectionString": "Server=(localdb)mssqllocaldb;Database=ApplicationDb;Trusted_Connection=True;MultipleActiveResultSets=true","DecAppDbConnectionString": "Server=Server=(localdb)mssqllocaldb;Database=DecAppDb;Trusted_Connection=True;MultipleActiveResultSets=true"
  }
}

您在其中定义两个连接字符串.

几秒钟,你声明了以DbContext为基类的类DecAppContext和ApplicationDbContext.最简单的形式就是

public class ApplicationDbContext : DbContext
{
}
public class DecAppContext : DbContext
{
}

没有任何DbSet属性.

第三步.您使用Microsoft.Extensions.DependencyInjection注入数据库上下文.要做到这一点,你需要在Startup.cs中加入类似的内容

public class Startup
{
    // property for holding configuration
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddEnvironmentVariables();
        // save the configuration in Configuration property
        Configuration = builder.Build();
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddMvc()
            .AddJsonOptions(options => {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        services.AddEntityFramework()
            .AddSqlServer()
            .AddDbContext<ApplicationDbContext>(options => {
                options.UseSqlServer(Configuration["Data:ApplicationDbConnectionString"]);
            })
            .AddDbContext<DecAppContext>(options => {
                options.UseSqlServer(Configuration["Data:DecAppDbConnectionString"]);
            });
    }
    public void Configure(IApplicationBuilder app,IHostingEnvironment env,ILoggerFactory loggerFactory)
    {
        ...
    }
}

使用配置“Data:DecAppDbConnectionString”和“Data:ApplicationDbConnectionString”创建两个DbContext(DecAppContext和ApplicationDbContext).

现在我们可以在控制器中使用上下文.例如

[Route("api/[controller]")]
public class UsersController : Controller
{
    [FromServices]
    public ApplicationDbContext ApplicationDbContext { get; set; }

    [FromServices]
    public DecAppContext DecAppContext { get; set; }

    [HttpGet]
    public IEnumerable<object> Get() {
        var returnObject = new List<dynamic>();

        using (var cmd = ApplicationDbContext.Database.GetDbConnection().CreateCommand()) {
            cmd.CommandText = "SELECT Id,FirstName FROM dbo.Users";
            if (cmd.Connection.State != ConnectionState.Open)
                cmd.Connection.Open();

            var retObject = new List<dynamic>();
            using (var dataReader = cmd.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    var dataRow = new ExpandoObject() as IDictionary<string,object>;
                    for (var iFiled = 0; iFiled < dataReader.FieldCount; iFiled++)
                        dataRow.Add(
                            dataReader.GetName(iFiled),dataReader.IsDBNull(iFiled) ? null : dataReader[iFiled] // use null instead of {}
                        );

                    retObject.Add((ExpandoObject)dataRow);
                }
            }
            return retObject;
        }
    }
}

或使用async / await相同:

[Route("api/[controller]")]
public class UsersController : Controller
{
    [FromServices]
    public ApplicationDbContext ApplicationDbContext { get; set; }

    [FromServices]
    public DecAppContext DecAppContext { get; set; }

    [HttpGet]
    public async IEnumerable<object> Get() {
        var returnObject = new List<dynamic>();

        using (var cmd = ApplicationDbContext.Database.GetDbConnection().CreateCommand()) {
            cmd.CommandText = "SELECT Id,FirstName FROM dbo.Users";
            if (cmd.Connection.State != ConnectionState.Open)
                cmd.Connection.Open();

            var retObject = new List<dynamic>();
            using (var dataReader = await cmd.ExecuteReaderAsync())
            {
                while (await dataReader.ReadAsync())
                {
                    var dataRow = new ExpandoObject() as IDictionary<string,object>;
                    for (var iFiled = 0; iFiled < dataReader.FieldCount; iFiled++)
                        dataRow.Add(dataReader.GetName(iFiled),dataReader[iFiled]);

                    retObject.Add((ExpandoObject)dataRow);
                }
            }
            return retObject;
        }
    }
}

可以只声明属性public ApplicationDbContext ApplicationDbContext {get;组;使用属性[FromServices]和ASP.NET从ConfigureServices中注入的上下文初始化它.以同样的方式,您可以在需要时使用第二个上下文DecAppContext.

上面的代码示例将在数据库上下文中执行SELECT Id,FirstName来自dbo.Users并返回格式为[{“id”:123,“firstName”:“Oleg”},{“id”:456,“名字 “:” Xaxum“}].由于在ConfigureServices中使用AddJsonOptions,因此在序列化期间将自动将Id和FirstName的属性名称转换为id和firstName.

更新:我必须参考the announcement.下一版本的MVC(RC2)将需要更改上面的代码以使用[FromServices]作为附加参数(例如方法Get())而不是使用公共属性[FromServices] public ApplicationDbContext ApplicationDbContext {get;组; }.需要删除属性ApplicationDbContext并向Get()方法添加其他参数:public async IEnumerable< object>获取([FromServices] ApplicationDbContext applicationDbContext){…}.这样的改变很容易完成.请参阅here以及MVC演示示例中的更改示例:

[Route("api/[controller]")]
public class UsersController : Controller
{
    [HttpGet]
    public async IEnumerable<object> Get(
                     [FromServices] ApplicationDbContext applicationDbContext,[FromServices] DecAppContext decAppContext)
    {
        var returnObject = new List<dynamic>();

        // ...  the same code as before,but using applicationDbContext 
        // and decAppContext parameters instead of ApplicationDbContext
        // and DecAppContext properties
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读