複数のdbcontextを作成するMVC 6 EF7 RC1

asp.net-core-mvc entity-framework-core

質問

私はEF7 RC1で2番目のDBコンテキストを作成する方法を理解しようとしています。過去に私は:base( "connectionName")でコンストラクタを使うことができましたが、それは文字列をSystem.IServiceProviderに変換できないという理由で、もはやオプションのようには見えません。

私の2番目のコンテキストコードは次のとおりです:

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);

私はエラーが表示されます:

データベースプロバイダは構成されていません。 DbContextクラスのOnConfiguringまたはサービスの設定時にAddDbContextメソッドをオーバーライドして、データベースプロバイダを構成します。

複数のDBコンテキストを持つEF7 RC1の実例とそれにアクセスすることは、非常に感謝しています。

受け入れられた回答

まず、GitHubのEntityFrameworkのwikiの記事をお勧めします。この記事では、 appsettings.jsonセクションを参照するDbContextを定義するDbContextな方法について説明します。私は個人的に[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"
  }
}

2つの接続文字列を定義します。

秒あなたは、クラス宣言DecAppContextApplicationDbContextているDbContextベース・クラスとしては。最も単純な形式は、

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

DbSetプロパティは一切ありませDbSet

第3ステップ。 Microsoft.Extensions.DependencyInjectionを使用して、データベースコンテキストを挿入します。これを行うには、 Startup.cs次のようなものを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)
    {
        ...
    }
}

Seは、 "Data:DecAppDbConnectionString""Data:ApplicationDbConnectionString"の設定を使用して2つのDbContextDecAppContextApplicationDbContext )を作成します。

これでコントローラのコンテキストを使うことができます。例えば

[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;
        }
    }
}

1つはプロパティを宣言するだけです。Public public ApplicationDbContext ApplicationDbContext { get; set; }を属性[FromServices][FromServices] 、ASP.NETはConfigureServices挿入されたコンテキストから初期化します。同様に、必要に応じてDecAppContextという2番目のコンテキストを使用することができます。

上記のコード例では、データベースコンテキスト内のSELECT Id, FirstName From dbo.Usersを実行し、JSONデータを[{"id":123, "firstName":"Oleg"},{"id":456, "firstName":"Xaxum"}]IdFirstNameからidfirstNameへのプロパティ名の変換は、 ConfigureServicesの使用法AddJsonOptionsために、シリアル化中に自動的に行われます。

更新:私は発表を参照する必要があります。 MVC(RC2)の次のバージョンでは、代わりに[FromServices]を使用するために、上記のコードを変更する必要があります(例Get()メソッドGet() [FromServices] public ApplicationDbContext ApplicationDbContext { get; set; } public property [FromServices] public ApplicationDbContext ApplicationDbContext { get; set; } 。プロパティーApplicationDbContextを削除し、 Get()メソッドに追加のパラメーターを追加する必要がありますpublic async IEnumerable<object> Get([FromServices] ApplicationDbContext applicationDbContext) {...} 。そのような変更は簡単に行うことができます。参照してくださいここと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
    }


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ