Drugi raz w tym projekcie czułem się w beznadziejnej sytuacji kiedy próbowałem coś zaimplementować, a nic nie chciało działać. Szukanie błędów jest dla mnie fajną sprawą dopóki nie uważam, że zrobiłem wszystko jak należy a coś dalej nie działa. Wtedy nachodzi mnie konsternacja i zrezygnowanie. W takich momentach najlepiej sprawdza się w moim przypadku przerwa na co najmniej pół godziny.
Zaczęło się niewinnie. Odpaliłem VS, chciałem skompliować projekt i wyskoczył mi błąd:
An error occurred attempting to determine the process id of the DNXprocess hosting your application.
Niestety pierwsze wyniki w googlu mi nie pomogły (StackOverFlow). Gdzieś znalazłem wskazówkę, żeby odpalić projekt przy użyciu opcji „Start project without debbuging” (Ctrl+F5). I dzięki temu zabiegowi otrzymałem bardziej znaczący błąd:
The configuration section ‚entityFramework’ cannot be read because it is missing a section declaration
Znalazłem na Stacku informację, że to może być wina web.configa. Na początku mój web.config wyglądał tak:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/> </handlers> <httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/> </system.webServer> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> <parameters> <parameter value="mssqllocaldb" /> </parameters> </defaultConnectionFactory> <providers> <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> </providers> </entityFramework> </configuration>
Po zastosowaniu się do propozycji naprawy tego błędu ze Stacka dodałem do web.configa linijkę:
<configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> </configuration>
Po prawdzie projekt kompilował się już, ale to rozwiązanie jakoś mi się nie podobało. Zrobiłem małe dochodzenie: odpaliłem nowy projekt -> zrobiłem na szybko EF First Code Approach i odkryłem, że w nowym projekcie nie ma całej sekcji entityFramework. Wyrzuciłem więc tą sekcję i projekt się dalej kompilował i działał. Więc idąc tym tropem mój nowy web.config prezentował się tak:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <handlers> <add name="httpPlatformHandler" path="*" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/> </handlers> <httpPlatform processPath="%DNX_PATH%" arguments="%DNX_ARGS%" stdoutLogEnabled="false" startupTimeLimit="3600"/> </system.webServer> </configuration>
Następnie stwierdziłem, że sprawdzę czy EF zaciąga dane z bazy danych. Dodałem nowy rekord do bazy danych i spróbowałem skompilować. Dostałem po oczach nowym błędem:
Additional information: No database providers are configured. Configure a database provider by overriding OnConfiguring in your DbContext class or in the AddDbContext method when setting up services.
Błąd pojawił się na linijce:
return Context.Set<TEntity>().ToList();
Czyli w miejscu gdzie strikte odwoływałem się do bazy danych. Rozwiązaniem może być na przykład stworzenie odpowiedniego konstruktora, bądź nadpisanie metody OnConfiguring.
public class ApplicationContext : DbContext { public DbSet<Player> Players { get; set; } public DbSet<Tournament> Tournaments { get; set; } public DbSet<Venue> Venues { get; set; } public DbSet<Achievement> Achievements { get; set; } public DbSet<Result> Results { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder options) { options.UseSqlServer("Data Source=TOMASZ\\SQLEXPRESS;Initial Catalog=PokerWebsite;Integrated Security=True"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entity in modelBuilder.Model.GetEntityTypes()) { modelBuilder.Entity(entity.Name).ToTable(entity.Name + "s"); } modelBuilder.Entity<Result>().HasKey(x => new { x.PlayerID, x.TournamentID }); modelBuilder.Entity<PlayerAchievement>().HasKey(x => new { x.PlayerID, x.AchievementID }); } }