2017-09-14 64 views
5

Bu konuda SO ile ilgili benzer örneklerden bazılarını görmüştüm ama henüz yanlış yaptığımı görmek için bu dili yeterince bilmiyorum. Daha fazla bilgi edinmek için bir demoyu bir araya getirdim ama veritabanımı eklerken sorun yaşıyorum.ASP.NET Çekirdek 2 Çekirdek Veritabanı

Modeller/AppDbContext.cs

public class AppDbContext : DbContext 
{ 
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) 
    { 

    } 
    public DbSet<Product> Products{ get; set; } 
    public DbSet<Category> Categories { get; set; } 
} 

Modeller/DBInitializer.cs: Burada

InvalidOperationException: Cannot resolve scoped service 'demoApp.Models.AppDbContext' from root provider.

Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteValidator.ValidateResolution(Type serviceType, ServiceProvider serviceProvider)

Söz konusu üç dosyalar şunlardır:

aşağıdaki hatayı alıyorsunuz

public static class DbInitializer 
{ 
    public static void Seed(IApplicationBuilder applicationBuilder) 
    { 
     //I'm bombing here 
     AppDbContext context = applicationBuilder.ApplicationServices.GetRequiredService<AppDbContext>(); 

     if (!context.Products.Any()) 
     { 
      // Add range of products 
     } 

     context.SaveChanges(); 
    } 

    private static Dictionary<string, Category> _categories; 
    public static Dictionary<string, Category> Categories 
    { 
     get 
     { 
      if (_categories == null) 
      { 
       // Add categories... 
      } 

      return _categories; 
     } 
    } 
} 

Startup.cs

public Startup(IConfiguration configuration) 
{ 
    Configuration = configuration; 
} 

public IConfiguration Configuration { get; } 

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddTransient<ICategoryRepository, CategoryRepository>(); 
    services.AddTransient<IProductRepository, ProductRepository>(); 

    services.AddDbContext<AppDbContext>(options => 
     options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 

    services.AddMvc(); 
} 

public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
{ 
    if (env.IsDevelopment()) 
    { 
     app.UseDeveloperExceptionPage(); 
     app.UseBrowserLink(); 
     app.UseStatusCodePages(); 

     // Kersplat! 
     DbInitializer.Seed(app); 
    } 
    else ... 

    app.UseStaticFiles(); 
    app.UseMvc(routes => {...}); 
} 

birisi yanlış yaptığını ve nasıl durumu düzeltmek için ettiğimi açıklamak yardımcı olabilir misiniz? Orijinal Yanıtı

cevap

11

ASP.NET Core 2.0'da aşağıdaki değişiklikler önerilir. (Başlangıçta Çekirdek 1.x için çalışır. 2.0 için Program.cs'a gidin, uygulama başlangıcında aşağıdakileri yapmak için Ana yöntemi değiştirin: Bağımlılık enjeksiyon kapsayıcısından bir veritabanı içeriği örneği alın. Tohum yöntemini çağırın. bunun bağlam geçen. tohum yöntemi yapılır bağlamı bertaraf edin. (Burada, Microsoft sitesinden bir örnek. https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro) Ben göçler reran güncellenen veritabanı ve beklendiği gibi veritabanı seribaşı

public static void Main(string[] args) 
{ 
var host = BuildWebHost(args); 

using (var scope = host.Services.CreateScope()) 
{ 
    var services = scope.ServiceProvider; 
    try 
    { 
     var context = services.GetRequiredService<yourDBContext>(); 
     DbInitializer.Seed(context);//<---Do your seeding here 
    } 
    catch (Exception ex) 
    { 
     var logger = services.GetRequiredService<ILogger<Program>>(); 
     logger.LogError(ex, "An error occurred while seeding the database."); 
    } 
} 

host.Run(); 
} 
+0

Neden 'Main'? 'Yi değiştirmek neden tercih edildiğine dair bir referans var mı? –

+1

I Bağlantılı makalede, yukarıdaki kodun hemen altından bahseder. "Eski öğreticilerde, Startup.cs'deki Yapılandırma yönteminde benzer kod görebilirsiniz. Yapılandırma yöntemini yalnızca istek boru hattını ayarlamak için kullanmanızı öneririz. Uygulama başlatma kodu Ana yönteme aittir." – palehorse

+0

NB: CreateScope yönteminin kullanılabilmesi için aşağıdaki ifadeye gereksinim vardır: 'Microsoft.Extensions.DependencyInjection;' kullanarak. – JohnLBevan

2

Güncelleme: Ben de hiçbir .NET Çekirdek uzman değilim

ama bu: .NET Çekirdek 2.0 için

, this answer yerine

Orijinal Cevap göz atın senin çözümün olabilir.

olarak DBInitializer.cs

public static void Seed(IApplicationBuilder applicationBuilder) 
    { 
     using (var serviceScope = applicationBuilder.ApplicationServices.GetRequiredService<IServiceScopeFactory>() 
       .CreateScope()) 
     { 
      AppDbContext context = serviceScope.ServiceProvider.GetService<AppDbContext>(); 

      if (!context.Products.Any()) 
      { 
       // Seed Here 
      } 

      context.SaveChanges(); 
     } 
    } 

hata bağlam kapsamlı gerektiğini göstermektedir.

Ayrıca, daha önce yapmadıysanız, Introduction to Dependency Injection in ASP.NET Core belgesine, ancak daha ayrıntılı olarak Service Lifetimes and Registration Options bölümüne bakarım.

+0

Sağladığınız linkleri çok beğendim.Çok teşekkürler .. – forcequitIO

İlgili konular