MVC Core - książka z nieaktualnym(?) przykładem metody EnsurePopulated w klasie DataSeed

0

Witam, mam taki problem otóż przerabiam książkę "ASP.NET Core MVC 2. Zaawansowane programowanie". Przy tworzeniu kompletnej aplikacji od zera mam problem. Otóż tworzę klasę SeedData.cs, natomiast kod z książki jest chyba nieaktualny(?), bo nie mam dostępu i w ogóle nie istnieje taka metoda. Poniższy link odnosi do przykładu kodu z książki na githubie:
https://github.com/Apress/pro-asp.net-core-mvc/blob/master/Source%20Code%201-31/12%20-%20SportsStore%20-%20Security%20and%20Deployment/SportsStore/src/SportsStore/Models/SeedData.cs

Problem jest tutaj:

ApplicationDbContext context = app.ApplicationServices
                .GetRequiredService<ApplicationDbContext>();

U siebie w kodzie nie mam metody GetRequiredService<>() tylko GetService(typ serwisu). Z resztą ta metoda wygląda następująco:

public interface IServiceProvider
    {
        //
        // Summary:
        //     Gets the service object of the specified type.
        //
        // Parameters:
        //   serviceType:
        //     An object that specifies the type of service object to get.
        //
        // Return:
        //     A service object of type serviceType. -or- null if there is no service object
        //     of type serviceType.
        object GetService(Type serviceType);
    }

Niestety nie jestem aż tak obeznany żeby na własną rękę próbować to konfigurować, więc proszę Was mądre głowy o pomoc

#Edit
Chyba że w wersji Core 2.1 zmienili i inaczej się pobiera ten serwis, jeśli tak to byłby w stanie ktoś pomóc czy podesłać jakieś pomocne linki i ew. wytłumaczył co będzie dla mnie nie do końca jasne?

0

W

Startup.cs w metodzie Configure przekazuje on IApplicationBuilder app, który następnie używany jest w SeedData.EnsurePopulated(app);, który następnie wczytuje sobie context i wypełnia go danymi.

Równie dobrze mógłbyś przekazać w tych dwóch miejscach context i bezpośrednio na nim działać.

1

Jeśli korzystasz z EF Core 2.1 możesz zrobić coś takiego, nadpisać metodę OnModelCreating w AppDbContext, w której wskażesz klasę z konfiguracją, gdzie będziesz dodawał tymczasowe dane. Klasa ta musi implementować IEntityTypeConfiguration<T>

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.ApplyConfiguration(new ProductConfig());
}
public class ProductConfig : IEntityTypeConfiguration<Product>
{
	public void Configure(EntityTypeBuilder<Product> builder)
	{
		builder.HasData(
			new Product(),
			new Product(),
			new Product(),
			new Product()
		);
	}
}
0
Aenyatia napisał(a):

Jeśli korzystasz z EF Core 2.1 możesz zrobić coś takiego, nadpisać metodę OnModelCreating w AppDbContext, w której wskażesz klasę z konfiguracją, gdzie będziesz dodawał tymczasowe dane. Klasa ta musi implementować IEntityTypeConfiguration<T>

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.ApplyConfiguration(new ProductConfig());
}
public class ProductConfig : IEntityTypeConfiguration<Product>
{
	public void Configure(EntityTypeBuilder<Product> builder)
	{
		builder.HasData(
			new Product(),
			new Product(),
			new Product(),
			new Product()
		);
	}
}

Ta klasa ProductConfig też ma być w katalogu Models?

0

Nie, ja to trzymam w infrastrukturze bo to jest klasa konfiguracyjna ef core, nie ma nic wspólnego z domeną.

0

Możesz np. zrobić folder o nazwie Infrastructure, Persistance albo EF Core i tam trzymać klasy konfiguracyjne, jeśli chcesz to może być również nowy projekt w solucji. Wszystko zależy od projektu.

  • Controllers
  • Models
  • Views
  • Infrastructure
    • AppDbContext.cs
    • Configurations - folder z konfiguracjami
      • ProductConfiguration
      • konfiguracje innych klas
0
Aenyatia napisał(a):

Jeśli korzystasz z EF Core 2.1 możesz zrobić coś takiego, nadpisać metodę OnModelCreating w AppDbContext, w której wskażesz klasę z konfiguracją, gdzie będziesz dodawał tymczasowe dane. Klasa ta musi implementować IEntityTypeConfiguration<T>

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
	modelBuilder.ApplyConfiguration(new ProductConfig());
}
public class ProductConfig : IEntityTypeConfiguration<Product>
{
	public void Configure(EntityTypeBuilder<Product> builder)
	{
		builder.HasData(
			new Product(),
			new Product(),
			new Product(),
			new Product()
		);
	}
}

AppDbContext które dziedziczy po DbContext robi mały problem:

Not found method to override

Może podam kod, ApplicationDbContext:

namespace SportsStore.Models
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) 
            : base(options)
        {
        }

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

appsettings.json (też się teraz podaje ten connection string?):

{
  "Data": {
    "SportsStoreProducts": {
      "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;DataBase=SportsStore;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  }
}

program.cs:

public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseDefaultServiceProvider(options =>
                    options.ValidateScopes = false);
    }

W startup.cs też dodany jest kontekst:

services.AddDbContext<ApplicationDbContext>(options => 
                options.UseSqlServer(Configuration["Data:SportsStoreProducts:ConnectionString"]));
            services.AddTransient<IProductRepository, EFProductRepository>();

No i jak już daje wszystko to repozytorium:

public class EFProductRepository : IProductRepository
    {
        private readonly ApplicationDbContext context;

        public EFProductRepository(ApplicationDbContext context)
        {
            this.context = context;
        }

        public IQueryable<Product> Products => context.Products;
    }

Jakby ktoś mógł zerknąć czy to co tu widać dalej się tak stosuje czy już jakoś inaczej, byłbym bardzo wdzięczny

#Edit
W książce przed tym Seedem musiałem zrobić migrację i w konsoli wpisać

dotnet ef migration add Initial

W przykładzie podobnym do tego co napisała mi Aenyatia gość użył tego polecenia po tym nadpisaniu, to może być źródło jakiegoś problemu?

0

Kurde nie wiem jakim cudem wcześniej mi coś wywalało, spróbowałem teraz i jest ok, dziękuje bardzo! Czyli rozumiem że jak w tym starszym sposobie w startup dodawało się tą metodę z klasy SeedData teraz już nic nie muszę tam dodawać?

ApplicationDbContent.cs:

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

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new ProductConfig());
        }

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

ProductConfig.cs

public class ProductConfig : IEntityTypeConfiguration<Product>
    {
        public void Configure(EntityTypeBuilder<Product> builder)
        {
            builder.HasData(
                new Product
                {
                    ...
                }, new Product
                {
                    ...
                }, new Product
                {
                    ...
                }, new Product
                {
                    ..
                }, new Product
                {
                    ...
                }, new Product
                {
                    ...
                }, new Product
                {
                    ...
                }, new Product
                {
                    ...
                }, new Product
                {
                    ...
                }
                );
        }
    }

W srartup.cs mam ten fragment:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ApplicationDbContext>(options => 
                options.UseSqlServer(Configuration["Data:SportsStoreProducts:ConnectionString"]));
            services.AddTransient<IProductRepository, EFProductRepository>();
            
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

W program.cs ten DefaultServiceProvider jest teraz potrzebny?

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseDefaultServiceProvider(options =>
                    options.ValidateScopes = false);

I co ja teraz muszę zrobić żeby wszystko było ok? Gdzieś w necie widziałem że gość teraz wpisał komendę

dotnet ef migrations add AddSeedData

i mu stworzyło partialową klasę dziedziczącą po klasie Migration, która wygląda u kogoś tak:

public partial class AddSeedData : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.InsertData(
            table: "Cars",
            columns: new[] { "CarId", "Make", "Model" },
            values: new object[] { 1, "Ferrari", "F40" });
 
        migrationBuilder.InsertData(
            table: "Cars",
            columns: new[] { "CarId", "Make", "Model" },
            values: new object[] { 2, "Ferrari", "F50" });
 
        migrationBuilder.InsertData(
            table: "Cars",
            columns: new[] { "CarId", "Make", "Model" },
            values: new object[] { 3, "Labourghini", "Countach" });
    }
 
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DeleteData(
            table: "Cars",
            keyColumn: "CarId",
            keyValue: 1);
 
        migrationBuilder.DeleteData(
            table: "Cars",
            keyColumn: "CarId",
            keyValue: 2);
 
        migrationBuilder.DeleteData(
            table: "Cars",
            keyColumn: "CarId",
            keyValue: 3);
    }
}

Link do tego przykładu wyżej -> https://rehansaeed.com/migrating-to-entity-framework-core-seed-data/
Tam jest w builderze użycia metoda Entity której np. ja nie mam i już się pogubiłem czy to jest tyle co trzeba, wystarczy odpalić apkę i wszystko gra czy coś jeszcze muszę zrobić?

0

Co się orientuję stara wersja ef core nie miała metody HasData() dlatego w Startup.cs się dodawało dane. Teraz masz wybór wybierz opcję która ci bardziej pasuje. W tym przykładzie co podałeś jest Entity bo jak widzisz dane są seedowane w AppDbContext a nie w "specjalistycznej klasie".

0
Aenyatia napisał(a):

Co się orientuję stara wersja ef core nie miała metody HasData() dlatego w Startup.cs się dodawało dane. Teraz masz wybór wybierz opcję która ci bardziej pasuje. W tym przykładzie co podałeś jest Entity bo jak widzisz dane są seedowane w AppDbContext a nie w "specjalistycznej klasie".

Ok dobra dzięki. Teraz natomiast mam błąd:

The seed entity for entity type 'Product' cannot be added because there was no value provided for the required property 'ProductId'.

builder.HasData(
                new Product
                {
                    Name = "Kajak",
                    Description = "Łódka przeznaczona dla jednej osoby",
                    Category = "Sporty wodne",
                    Price = 275M
                });

ProductId nie podaje bo dodałem annotacje:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int ProductId { get; set; }

po tym jak zrobiłem autoinkrementacje aktualizowałem bazę danych komendą:

dotnet ef database update
i wyskakuje to samo

Zielony jestem w tym temacie i dopiero zaczynam, a książka z czerwca już nieaktualna w niektórych sytuacjach ehh... ;/

0

Może spróbuj to od 0 walnąć

Tutaj taki przykład gdzie te Seedowanie tak bardzo chamsko zrobione, abyś tylko mógł od czegoś zacząć i najlepiej gdyby baza też się utworzyła sama, a nie próbować mieszać jakieś istniejące, tzn. da się, ale lepiej abyś nie zaliczył zderzenia z jakimś problemem :D

Musisz mieć SQL Server albo Expressa - nie pamiętam.

dotnet new mvc

public class YourModel
{
	[Key]
	public Guid Id { get; set; }

	public string Name { get; set; }
}
public class AppDbContext : DbContext
{
	public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
	{

	}

	public DbSet<YourModel> YourModels { get; set; }
}
public void ConfigureServices(IServiceCollection services)
{
	services.AddDbContext<AppDbContext>
	(
		options => options.UseSqlServer(Configuration["ConnectionString"])
	);

	services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, AppDbContext context)
{
	context.Database.EnsureCreated();

	if (env.IsDevelopment())
	{
		app.UseDeveloperExceptionPage();
	}
	else
	{
		app.UseExceptionHandler("/Home/Error");
		app.UseHsts();
	}

	// tutaj jest to słabo rozwiązane seedowanie, najlepiej jakbyś później gdzieś wywalił, przerobił itd.

	if (context.YourModels.Count() == 0)
	{
		context.YourModels.Add(new YourModel
		{
			Name = "Test"
		});
		context.SaveChanges();
	}

	app.UseHttpsRedirection();
	app.UseStaticFiles();
	app.UseCookiePolicy();

	app.UseMvc(routes =>
	{
		routes.MapRoute(
			name: "default",
			template: "{controller=Home}/{action=Index}/{id?}");
	});
}
{
  "ConnectionString": "Data Source=.\\SQLEXPRESS;Database=test;Integrated Security=True;",
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*"
}

0

Ogólnie zrobiłem projekt od nowa tylko w momencie gdzie w książce było utworzenie tej klasy SeedData zrobiłem tak jak napisała mi @Aenyatia i wygląda to następująco (wszystkie wszystkie powiązane pliki to może łatwiej będzie znaleźć problem):

IProductRepository:

public interface IProductRepository
    {
        IQueryable<Product> Products { get; }
    }

EFProductRepository:

public class EFProductRepository : IProductRepository
    {
        private readonly ApplicationDbContext context;

        public EFProductRepository(ApplicationDbContext context)
        {
            this.context = context;
        }

        public IQueryable<Product> Products => context.Products;
    }

ApplicationDbContext:

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

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.ApplyConfiguration(new ProductConfig());
        }

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

ProductConfig (zostawiam jeden przykładowy obiekt Product wypełnionymi danymi, tam i tak jest więcej tych obiektów niż tutaj):

public class ProductConfig : IEntityTypeConfiguration<Product>
    {
        public void Configure(EntityTypeBuilder<Product> builder)
        {
            builder.HasData(
                new Product
                {
                    Name = "Kajak",
                    Description = "Łódka przeznaczona dla jednej osoby",
                    Category = "Sporty wodne",
                    Price = 275
                }, new Product
                {
                    ...
                });
        }
    }

appsettings.json:

{
  "Data": {
    "SportStoreProducts": {
      "ConnectionString":  "Server=(localdb)\\MSSQLLocalDB;Database=SportsStore;Trusted_Connection=True;MultipleActiveResultSets=true"
    }
  }
}

Startup:

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

        public IConfiguration Configuration { get; }

        {
            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    Configuration["Data:SportStoreProducts:ConnectionString"]));
            services.AddTransient<IProductRepository, EFProductRepository>();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseStatusCodePages();
            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Product}/{action=List}/{id?}");
            });
        }
    }

Program.cs:

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
            .UseDefaultServiceProvider(options =>
                options.ValidateScopes = false);
    }

Teraz, utworzyłem migrację za pomocą komendy

dotnet ef migrations add Initial

Zrobiło mi migrację, plik 20181017214559_Initial:

public partial class Initial : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Products",
                columns: table => new
                {
                    ProductId = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    Name = table.Column<string>(nullable: true),
                    Price = table.Column<decimal>(nullable: false),
                    Description = table.Column<string>(nullable: true),
                    Category = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Products", x => x.ProductId);
                });

            migrationBuilder.InsertData(
                table: "Products",
                columns: new[] { "ProductId", "Category", "Description", "Name", "Price" },
                values: new object[,]
                {
                    { 1, "Sporty wodne", "Łódka przeznaczona dla jednej osoby", "Kajak", 275m },
                    { 2, "Sporty wodne", "Chroni i ratuje życie", "Kamizelka ratunkowa", 48.95m },
                    { 3, "Piłka nożna", "Zatwierdzona przez FIFA", "Piłka nożna", 19.50m },
                    { 4, "Piłka nożna", "Nadadzą Twojemu boisku profesjonalny wygląd", "Flagi narożne", 34.95m },
                    { 5, "Piłka nożna", "Składamy stadion na 3 500 osób", "Stadion", 79500m },
                    { 6, "Szachy", "Zwiększa efektywność mózgu o 75%", "Czapka", 16m },
                    { 7, "Szachy", "Zmniejsza szanse przeciwnika", "Niestabilne krzesło", 29.95m },
                    { 8, "Szachy", "Przyjemna gra dla całej rodziny", "Ludzka szachownica", 75m },
                    { 9, "Szachy", "Figura pokryta złotem i wysadzana diamentami", "Błyszczący król", 1200m }
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Products");
        }
    }

I plik ApplicationDbContextModelSnapshot:

[DbContext(typeof(ApplicationDbContext))]
    partial class ApplicationDbContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("ProductVersion", "2.1.4-rtm-31024")
                .HasAnnotation("Relational:MaxIdentifierLength", 128)
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

            modelBuilder.Entity("SportsStore.Models.Product", b =>
                {
                    b.Property<int>("ProductId")
                        .ValueGeneratedOnAdd()
                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

                    b.Property<string>("Category");

                    b.Property<string>("Description");

                    b.Property<string>("Name");

                    b.Property<decimal>("Price");

                    b.HasKey("ProductId");

                    b.ToTable("Products");

                    b.HasData(
                        new { ProductId = 1, Category = "Sporty wodne", Description = "Łódka przeznaczona dla jednej osoby", Name = "Kajak", Price = 275m },
                        new { ProductId = 2, Category = "Sporty wodne", Description = "Chroni i ratuje życie", Name = "Kamizelka ratunkowa", Price = 48.95m },
                        new { ProductId = 3, Category = "Piłka nożna", Description = "Zatwierdzona przez FIFA", Name = "Piłka nożna", Price = 19.50m },
                        new { ProductId = 4, Category = "Piłka nożna", Description = "Nadadzą Twojemu boisku profesjonalny wygląd", Name = "Flagi narożne", Price = 34.95m },
                        new { ProductId = 5, Category = "Piłka nożna", Description = "Składamy stadion na 3 500 osób", Name = "Stadion", Price = 79500m },
                        new { ProductId = 6, Category = "Szachy", Description = "Zwiększa efektywność mózgu o 75%", Name = "Czapka", Price = 16m },
                        new { ProductId = 7, Category = "Szachy", Description = "Zmniejsza szanse przeciwnika", Name = "Niestabilne krzesło", Price = 29.95m },
                        new { ProductId = 8, Category = "Szachy", Description = "Przyjemna gra dla całej rodziny", Name = "Ludzka szachownica", Price = 75m },
                        new { ProductId = 9, Category = "Szachy", Description = "Figura pokryta złotem i wysadzana diamentami", Name = "Błyszczący król", Price = 1200m }
                    );
                });
#pragma warning restore 612, 618
        }
    }

Te 2 pliki utworzyło mi w katalogu Mirations. I teraz po odpaleniu apki wyskakuje błąd że ProductId jest nullem, natomiast gdzieś w necie wyczytałem że wystarczy pierwszą migrację zrobić podając id na sztywno, a potem te id będą się same wypełniać, więc idąc tym tropem uzupełniłem ProductId we wszystkich obiektach, po odpaleniu mam taki problem:

SqlException: Cannot open database "SportsStore" requested by the login. The login failed.
Login failed for user 'DESKTOP-69SKPHN\Papryk'.

Tak więc coś się z loginem chyba nie zgadza. Mam wiele niejasności, np. czy w tym pliku Program.cs dalej trzeba użyć metody UseDefaultServiceProvider i ustawiać ValidateScopes na false, czy ten ConnectionString jest dobry, może inaczej jakoś to się teraz robi. Mogę to jeszcze raz od nowa napisać jeśli coś popsułem w migracjach, ogólnie ciężki temat.

#Edit
Probowałem się połączyć ręcznie z bazą, wpisałem w visualu ręcznie nazwę tego serwera i jak chciałem znaleźć jakąkolwiek nazwę bazy to po chwili wczytywania wyrzuciło mi taki błąd:

0

Dobra dzięki za pomoc ale jednak zacznę to przerabiać w Core 2.0. Tam później jest wszystko opisane i powoli będę się zagłębiał w szczegóły MVC Core żeby potem płynniej przejść na wersję 2.1. na razie to nie ma sensu bo pewnie sporo się w książce nie będzie zgadzać i to tylko narobi więcej problemów biorąc pod uwagę że dopiero się uczę.

0
public class Program
{
	public static void Main(string[] args)
		=> CreateWebHostBuilder(args).Build().Run();

	public static IWebHostBuilder CreateWebHostBuilder(string[] args)
		=> WebHost.CreateDefaultBuilder(args)
			.UseStartup<Startup>();
}

public class Startup
{
	public IConfiguration Configuration { get; }

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

	public void ConfigureServices(IServiceCollection services)
	{
		services.AddMvc();
		services.AddDbContext<AppDbContext>(options =>
			options.UseSqlServer(Configuration.GetConnectionString("AppConnection")));
	}

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

		app.UseMvcWithDefaultRoute();
	}
}

public class AppDbContext : DbContext
{
	public DbSet<Product> Products { get; set; }

	public AppDbContext(DbContextOptions options)
			: base(options)
	{
	}

	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.ApplyConfiguration(new ProductConfig());
	}
}

public class ProductConfig : IEntityTypeConfiguration<Product>
{
	public void Configure(EntityTypeBuilder<Product> builder)
	{
		builder.HasData(
			new Product { Id = 1, Name = "A" },
			new Product { Id = 2, Name = "B" },
			new Product { Id = 3, Name = "C" }
		);
	}
}

"ConnectionStrings": {
	"AppConnection": "Server=(localdb)\\MSSQLLocalDB;Database=AspCoreMvc;Trusted_Connection=True;MultipleActiveResultSets=true"
}

W konsoli wpisujesz add-migration Initial potem update-database i tworzy się baza danych wypełniona testowymi danymi.

0
Aenyatia napisał(a):
public class Program
{
	public static void Main(string[] args)
		=> CreateWebHostBuilder(args).Build().Run();

	public static IWebHostBuilder CreateWebHostBuilder(string[] args)
		=> WebHost.CreateDefaultBuilder(args)
			.UseStartup<Startup>();
}

public class Startup
{
	public IConfiguration Configuration { get; }

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

	public void ConfigureServices(IServiceCollection services)
	{
		services.AddMvc();
		services.AddDbContext<AppDbContext>(options =>
			options.UseSqlServer(Configuration.GetConnectionString("AppConnection")));
	}

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

		app.UseMvcWithDefaultRoute();
	}
}

public class AppDbContext : DbContext
{
	public DbSet<Product> Products { get; set; }

	public AppDbContext(DbContextOptions options)
			: base(options)
	{
	}

	protected override void OnModelCreating(ModelBuilder modelBuilder)
	{
		modelBuilder.ApplyConfiguration(new ProductConfig());
	}
}

public class ProductConfig : IEntityTypeConfiguration<Product>
{
	public void Configure(EntityTypeBuilder<Product> builder)
	{
		builder.HasData(
			new Product { Id = 1, Name = "A" },
			new Product { Id = 2, Name = "B" },
			new Product { Id = 3, Name = "C" }
		);
	}
}

"ConnectionStrings": {
	"AppConnection": "Server=(localdb)\\MSSQLLocalDB;Database=AspCoreMvc;Trusted_Connection=True;MultipleActiveResultSets=true"
}

W konsoli wpisujesz add-migration Initial potem update-database i tworzy się baza danych wypełniona testowymi danymi.

No więc zrobiłem tak jak napisałeś już nawet w tym core 2.1. Jedyna zmiana to w tym startup dodałem services.AddTransient<IProductRepository, EFProductRepository>() ale dalej nie działa...
Robiłem to komendą "dotnet ef migrations add Initial bo niestety

'add-migration' is not recognized as an internal or external command,
operable program or batch file.

'update-database' is not recognized as an internal or external command,
operable program or batch file.

No i jestem na tym samym etapie co wtedy

SqlException: Cannot open database "SportsStore" requested by the login. The login failed.
Login failed for user 'DESKTOP-69SKPHN\Papryk'.

Czy naprawdę zmiany w visualu są tak odczuwalne że po update'ach już nic nie działa?

3

Przecież połączenie z db Ci nie działa(złe poświadczenia dajesz), a nie Visual czy .NET Core.

Dropnij ją w ***** i niech EF odnowa sobie utworzy :P

0
WeiXiao napisał(a):

Przecież połączenie z db Ci nie działa(złe poświadczenia dajesz), a nie Visual czy .NET Core.

Dropnij ją w ***** i niech EF odnowa sobie utworzy :P

Nie do końca zczaiłem, ja nie wiem dokładnie jak to wszystko pod spodem działa

@Aenyatia mam EFCore.Tools.DotNet 2.0.3

0

Tak z kodu usuwasz i tworzysz bazę

context.Database.EnsureDeleted();
context.Database.EnsureCreated();

I już wszystko powinno być OK.

Wrzuć to przed seedowanie.

0
pavarotti napisał(a):
WeiXiao napisał(a):

Przecież połączenie z db Ci nie działa(złe poświadczenia dajesz), a nie Visual czy .NET Core.

Dropnij ją w ***** i niech EF odnowa sobie utworzy :P

Nie do końca zczaiłem, ja nie wiem dokładnie jak to wszystko pod spodem działa

@Aenyatia mam EFCore.Tools.DotNet 2.0.3

Jakim cudem więc zabierasz się za programowanie nie mając pojęcia co się dzieje pod spodem!? Pytam poważnie teraz.

1

Oddaj komuś za darmo tą książkę, najlepiej komuś kogo bardzo nienawidzisz i kup sobie "Stephen King – Rage".

1 użytkowników online, w tym zalogowanych: 0, gości: 1