MVC 6 EF7 RC1创建多个dbcontext [英] MVC 6 EF7 RC1 creating multiple dbcontexts

查看:115
本文介绍了MVC 6 EF7 RC1创建多个dbcontext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何在EF7 RC1中创建第二个数据库上下文.过去,我可以将构造函数与:base("connectionName")一起使用,但由于它无法将字符串转换为System.IServiceProvider,因此似乎不再是一个选择.

I am trying to figure out how to create a second DB context in EF7 RC1. In the past I could use a constructor with :base("connectionName") but that no longer seems an option since it says cannot convert string to System.IServiceProvider.

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

My second context code is as follows:

public class DecAppContext : DbContext
    {

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

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

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

In my config.json I have the connection specified:

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

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

In my configure services section of my startup I have both contexts added:

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

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

The applicationDB context works fine since I can create a user and login without issue

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

However when I try to access the other context as in my controller via:

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

我得到了错误:

未配置数据库提供程序.通过以下方式配置数据库提供程序 在DbContext类或DbContext类中重写OnConfiguring 设置服务时使用AddDbContext方法.

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中具有多个数据库上下文并访问它们的任何工作示例将不胜感激.

Any working examples in EF7 RC1 with multiple db contexts and accessing them would be much appreciated.

推荐答案

首先,我建议您 GitHub上EntityFramework Wiki上的文章.本文介绍了许多定义DbContext的方法,这些方法引用了appsettings.json的一部分.我个人更喜欢使用[FromServices]属性的方式.

First of all I would recommend you the article from the wiki of EntityFramework on GitHub. The article describes many ways to define DbContext, which references to a section of appsettings.json. I personally prefer the way with the usage of [FromServices] attribute.

代码可能与以下内容有关:

The code could be about the following:

首先,您定义appsettings.json并包含以下内容

First of all you defined appsettings.json with the following content

{
  "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为基类的类DecAppContextApplicationDbContext.最简单的形式就是

Seconds you declare the classes DecAppContext and ApplicationDbContext which have DbContext as the base class. The simplest form will be just

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

没有任何DbSet属性.

第三步.您使用Microsoft.Extensions.DependencyInjection注入数据库上下文.为此,您只需在Startup.cs中添加类似

Third Step. You use Microsoft.Extensions.DependencyInjection to inject the database contexts. To do this you need just include in Startup.cs something like

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)
    {
        ...
    }
}

Se使用配置"Data:DecAppDbConnectionString""Data:ApplicationDbConnectionString"创建两个DbContext(DecAppContextApplicationDbContext).

Se create two DbContext (DecAppContext and ApplicationDbContext) using the configuration "Data:DecAppDbConnectionString" and "Data:ApplicationDbConnectionString".

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

Now we can just use the context in the controller. For example

[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相同:

or the same using 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;
        }
    }
}

只需声明具有属性[FromServices]的属性public ApplicationDbContext ApplicationDbContext { get; set; },ASP.NET将从注入到ConfigureServices中的上下文中对其进行初始化.同样,您可以在需要时使用第二个上下文DecAppContext.

One can just declare the property public ApplicationDbContext ApplicationDbContext { get; set; } with the attribute [FromServices] and ASP.NET initialize it from the context injected in ConfigureServices. In the same way one can use the second context DecAppContext whenever you need it.

上面的代码示例将在数据库上下文中执行SELECT Id, FirstName From dbo.Users,并以[{"id":123, "firstName":"Oleg"},{"id":456, "firstName":"Xaxum"}]的形式返回JSON数据.属性名称从IdFirstNameidfirstName的转换将在序列化过程中自动完成,因为在ConfigureServices中使用了AddJsonOptions.

The above code example will execute SELECT Id, FirstName From dbo.Users in the database context and return JSON data in the form [{"id":123, "firstName":"Oleg"},{"id":456, "firstName":"Xaxum"}]. The conversion of property names from Id and FirstName to id and firstName will be done automatically during serialization because of usage AddJsonOptions in ConfigureServices.

更新:我必须引用该公告. MVC(RC2)的下一版本将需要更改以上代码,以使用[FromServices]作为附加参数(例如,方法Get())而不是使用公共属性[FromServices] public ApplicationDbContext ApplicationDbContext { get; set; }.将需要删除属性ApplicationDbContext并将其他参数添加到Get()方法:public async IEnumerable<object> Get([FromServices] ApplicationDbContext applicationDbContext) {...}.这样的更改可以轻松完成.请参见此处以及MVC演示示例中的更改示例:

UPDATE: I have to reference the announcement. The next version of MVC (RC2) will require to change the above code to use [FromServices] as additional parameter (of method Get() for example) instead of usage public property [FromServices] public ApplicationDbContext ApplicationDbContext { get; set; }. One will need to remove the property ApplicationDbContext and to add additional parameter to Get() method: public async IEnumerable<object> Get([FromServices] ApplicationDbContext applicationDbContext) {...}. Such changes can be easy done. See here and example of the changes in the demo example of 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
    }

这篇关于MVC 6 EF7 RC1创建多个dbcontext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆