16

Sembra che in Entity Framework 7 non sia ancora disponibile il supporto nativo per i dati seme (https://github.com/aspnet/EntityFramework/issues/629).Dati iniziali seme in Entity Framework 7 RC 1 e ASP.NET MVC 6

Non esiste il codice, codice Seed nel codice del modello fornito da Microsoft.

Quindi, come eseguire il seeding dei dati nell'applicazione Web ASP.NET MVC 6 che utilizza Entity Framework 7 RC 1?

+1

È anche possibile vedere questo articolo nei blog MSDN: https://blogs.msdn.microsoft.com/dotnet/2016/09/29/implementing-seeding-custom-conventions-and-interceptors-in-ef-core-1-0/ –

risposta

15

Ho trovato una soluzione temporanea per me stesso.

Possiamo creare un metodo SeedData che estende il IApplicationBuilder quindi ottiene un'istanza della classe di contesto del nostro database tramite il metodo GetService e lo utilizza per il seeding dei dati.

Ecco come il mio metodo di estensione si presenta come:

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

di usarlo messo app.SeedData(); linea nel metodo dell'applicazione Startup classe Configure (situato nel progetto web in file chiamato Startup.cs).

// 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 
} 
2

ho creato metodo privato Seed() nel mio Startup.cs ma mi piace anche il tuo approccio perché può essere utilizzato non solo durante l'avvio dell'applicazione.

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(); 
    } 
} 
6

Per EF Nucleo RTM 1.0 e ASP.NET 1.0 RTM Nucleo

innanzitutto creare il metodo di seme. Ecco perché siamo fuori la portata della richiesta corrente, dobbiamo creare lo manulally:

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

     } 
    } 
} 

quindi specificare il tempo di vita corretta del ApplicationDbContext

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddDbContext<ApplicationDbContext>(ServiceLifetime.Scoped); 

E, infine richiamato il metodo SeedData() dal Configure metodo

public void Configure(IServiceScopeFactory scopeFactory) 
{ 
    scopeFactory.SeedData(); 
1

È possibile creare il metodo statico seme all'interno del ApplicationDbContext e passando IApplicationBuilder come un par ameter. Quindi chiama questo metodo nello 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; } 
} 

In Configure() metodo all'interno Startup.cs, chiamare il 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); 
    } 
2

Da EF/MVC intro, basta:

  1. dipendenza-iniettare il tuo DbContext (SchoolContext sotto) direttamente nella Startup.Configure() *
  2. passa il tuo DbContext a una funzione (DbInitializer.Initialize seguente) che fa qualcosa come:
    1. assicurarsi che il Database sia created or that it's migrated; context.Database.EnsureCreated(); considerano context.Database.Migrate();
    2. ritorni se già seminato if (context.Students.Any()) { return; }
    3. seme altro context.Students.Add({...}); context.SaveChanges();

Come qui:

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

* Dipendenza-iniettare nella Startup.Configure() è il motivo per cui la mia risposta è degno (anche se un'altra risposta è già accettata.)

  1. dipendenza-iniezione tuo DbContext in Startup.Configure() è fatto in EF/MVC Intro
  2. altra risposta qui solo la dipendenza -inizia in Configura; o GetService() e/o GetRequiredService() o istanziano un nuovoDbContext. Potrebbe non essere necessario tanto codice. Poi di nuovo, si potrebbe bisogno che molto codice, (cioè se il DbContext Dipendenza-iniettata era disposto, which is where the GetService() is necessary to create a new Scope.. Si prega di downvote/modificare/commento, se mi sbaglio qualcosa.
Problemi correlati