Entity Framework 7では、シードデータのネイティブサポートはまだないようです( https://github.com/aspnet/EntityFramework/issues/629 )。
マイクロソフトが提供するテンプレートコードには、DbMigrationsConfiguration
クラス、Seed
メソッドはありません。
では、Entity Framework 7 RC 1を使用するASP.NET MVC 6 Webアプリケーションにデータをシードする方法は?
私は一時的な回避策を見つけました。
SeedData
を拡張するメソッドIApplicationBuilder
を作成し、GetService
メソッドを介してデータベースコンテキストクラスのインスタンスを取得し、それをデータのシードに使用できます。
これが私の拡張メソッドがどのように見えるかです:
_using Microsoft.AspNet.Builder;
using Microsoft.Extensions.DependencyInjection;
public static class DataSeeder
{
// TODO: Move this code when seed data is implemented in EF 7
/// <summary>
/// This is a workaround for missing seed data functionality in EF 7.0-rc1
/// More info: https://github.com/aspnet/EntityFramework/issues/629
/// </summary>
/// <param name="app">
/// An instance that provides the mechanisms to get instance of the database context.
/// </param>
public static void SeedData(this IApplicationBuilder app)
{
var db = app.ApplicationServices.GetService<ApplicationDbContext>();
// TODO: Add seed logic here
db.SaveChanges();
}
}
_
これを使用するには、アプリケーションConfigure
クラスのStartup
メソッドにapp.SeedData();
行を配置します(_Startup.cs
_というファイルのWebプロジェクトにあります)。
_// This method gets called by the runtime.
// Use this method to configure the HTTP request pipeline.
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
app.SeedData();
// Other configuration code
}
_
EF Core RTM 1.0およびASP.NET Core RTM 1.0
最初にシードメソッドを作成します。ここでは、現在のリクエストの範囲外であるため、手動で作成する必要があります。
_using System.Collections.Generic;
using System.Linq;
using Core1RtmEmptyTest.Entities;
using Microsoft.Extensions.DependencyInjection;
namespace Core1RtmEmptyTest.Migrations
{
public static class ApplicationDbContextSeedData
{
public static void SeedData(this IServiceScopeFactory scopeFactory)
{
using (var serviceScope = scopeFactory.CreateScope())
{
var context = serviceScope.ServiceProvider.GetService<ApplicationDbContext>();
if (!context.Persons.Any())
{
var persons = new List<Person>
{
new Person
{
FirstName = "Admin",
LastName = "User"
}
};
context.AddRange(persons);
context.SaveChanges();
}
}
}
}
}
_
次に、ApplicationDbContextの正しい有効期間を指定します
_public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped);
_
そして最後にConfigure
メソッドからSeedData()
メソッドを呼び出します
_public void Configure(IServiceScopeFactory scopeFactory)
{
scopeFactory.SeedData();
_
私は_Startup.cs
_にプライベートSeed()
メソッドを作成しましたが、アプリケーションの起動時だけでなく使用できるため、あなたのアプローチも気に入っています。
_public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
this.Seed();
}
private void Seed()
{
using (var db = new MyDbContext())
{
db.Database.Migrate();
// Seed code
db.SaveChanges();
}
}
_
EF/MVC intro から:
DbContext
(以下の[SchoolContext
))をStartup.Configure()
*に直接挿入しますDbContext
を次のような関数(以下の_DbInitializer.Initialize
_)に渡します。context.Database.EnsureCreated();
考慮context.Database.Migrate();
if (context.Students.Any()) { return; }
を返しますcontext.Students.Add({...}); context.SaveChanges();
ここのような:
_public void Configure(..., ..., SchoolContext context)
{
...
DbInitializer.Initialize(context);
}
_
...
_public static class DbInitializer
{
public static void Initialize(SchoolContext context)
{
context.Database.EnsureCreated();
// Look for any students.
if (context.Students.Any())
{
return; // DB has been seeded
}
var students = new Student[]
{
new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")}, ...
};
foreach (Student s in students)
{
context.Students.Add(s);
}
context.SaveChanges();
...
_
* Startup.Configure()
への依存性注入が私の答えに値する理由です(別の答えがすでに受け入れられている場合でも)。
DbContext
のStartup.Configure()
への依存性注入は EF/MVC Intro で行われますGetService()
および/またはGetRequiredService()
のいずれか、または新しいDbContext
をインスタンス化します。あなたはそれほど多くのコードを必要としないかもしれません。次に、再びmay必要なコードが多くなります(つまり、Dependency-Injected DbContextが破棄された場合、 これはGetService()
は新しいスコープを作成するために必要です。 。私が何かについて誤っている場合は、投票/編集/コメントしてください。ApplicationDbContext内に静的シードメソッドを作成し、IApplicationBuilderをパラメーターとして渡すことができます。次に、このメソッドを_Startup.cs
_で呼び出します。
_ public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public static void Seed(IApplicationBuilder applicationBuilder)
{
using (var context=applicationBuilder.ApplicationServices.GetRequiredService<ApplicationDbContext>())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
for(int i = 1; i< 1000; i++)
{
context.Movies.Add(new Movie
{
Genre = "Action",
ReleaseDate =DateTime.Today,
Title = "Movie "+i
});
}
context.SaveChanges();
}
}
public DbSet<Movie> Movies { get; set; }
}
_
_Startup.cs
_内のConfigure()
メソッドで、ApplicationDbContext.Seed(app)
を呼び出します
_ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
ApplicationDbContext.Seed(app);
}
_